Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: trunk/src/ash/sticky_keys/sticky_keys_unittest.cc

Issue 341923006: Revert 278342 "Convert sticky keys to a chromeos::EventRewriter ..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/sticky_keys/sticky_keys_controller.h" 5 #include "ash/sticky_keys/sticky_keys_controller.h"
6 6
7 #include <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 #undef None 8 #undef None
9 #undef Bool 9 #undef Bool
10 #undef RootWindow 10 #undef RootWindow
11 11
12 #include "ash/shell.h" 12 #include "ash/shell.h"
13 #include "ash/test/ash_test_base.h" 13 #include "ash/test/ash_test_base.h"
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/memory/scoped_vector.h" 16 #include "base/memory/scoped_vector.h"
17 #include "ui/aura/window.h" 17 #include "ui/aura/window.h"
18 #include "ui/aura/window_tree_host.h" 18 #include "ui/aura/window_tree_host.h"
19 #include "ui/events/event_source.h" 19 #include "ui/events/event_handler.h"
20 #include "ui/events/event_processor.h"
20 #include "ui/events/test/events_test_utils_x11.h" 21 #include "ui/events/test/events_test_utils_x11.h"
21 #include "ui/events/x/device_data_manager.h" 22 #include "ui/events/x/device_data_manager.h"
22 23
23 namespace ash { 24 namespace ash {
24 25
25 namespace { 26 namespace {
26 27
27 // The device id of the test touchpad device. 28 // The device id of the test touchpad device.
28 const unsigned int kTouchPadDeviceId = 1; 29 const unsigned int kTouchPadDeviceId = 1;
29 30
30 } // namespace 31 } // namespace
31 32
32 class StickyKeysTest : public test::AshTestBase { 33 // Keeps a buffer of handled events.
34 class EventBuffer : public ui::EventHandler {
35 public:
36 EventBuffer() {}
37 virtual ~EventBuffer() {}
38
39 void PopEvents(ScopedVector<ui::Event>* events) {
40 events->clear();
41 events->swap(events_);
42 }
43
44 private:
45 // ui::EventHandler overrides:
46 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
47 events_.push_back(new ui::KeyEvent(*event));
48 }
49
50 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
51 if (event->IsMouseWheelEvent()) {
52 events_.push_back(
53 new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent*>(event)));
54 } else {
55 events_.push_back(new ui::MouseEvent(*event));
56 }
57 }
58
59 ScopedVector<ui::Event> events_;
60
61 DISALLOW_COPY_AND_ASSIGN(EventBuffer);
62 };
63
64 // A testable and StickyKeysHandler.
65 class MockStickyKeysHandlerDelegate :
66 public StickyKeysHandler::StickyKeysHandlerDelegate {
67 public:
68 class Delegate {
69 public:
70 virtual aura::Window* GetExpectedTarget() = 0;
71 virtual void OnShortcutPressed() = 0;
72
73 protected:
74 virtual ~Delegate() {}
75 };
76
77 MockStickyKeysHandlerDelegate(Delegate* delegate) : delegate_(delegate) {}
78
79 virtual ~MockStickyKeysHandlerDelegate() {}
80
81 // StickyKeysHandler override.
82 virtual void DispatchKeyEvent(ui::KeyEvent* event,
83 aura::Window* target) OVERRIDE {
84 ASSERT_EQ(delegate_->GetExpectedTarget(), target);
85
86 // Detect a special shortcut when it is dispatched. This shortcut will
87 // not be hit in the LOCKED state as this case does not involve the
88 // delegate.
89 if (event->type() == ui::ET_KEY_PRESSED &&
90 event->key_code() == ui::VKEY_J &&
91 event->flags() | ui::EF_CONTROL_DOWN) {
92 delegate_->OnShortcutPressed();
93 }
94
95 events_.push_back(new ui::KeyEvent(*event));
96 }
97
98 virtual void DispatchMouseEvent(ui::MouseEvent* event,
99 aura::Window* target) OVERRIDE {
100 ASSERT_EQ(delegate_->GetExpectedTarget(), target);
101 events_.push_back(
102 new ui::MouseEvent(*event, target, target->GetRootWindow()));
103 }
104
105 virtual void DispatchScrollEvent(ui::ScrollEvent* event,
106 aura::Window* target) OVERRIDE {
107 events_.push_back(new ui::ScrollEvent(event->native_event()));
108 }
109
110 // Returns the count of dispatched events.
111 size_t GetEventCount() const {
112 return events_.size();
113 }
114
115 // Returns the |index|-th dispatched event.
116 const ui::Event* GetEvent(size_t index) const {
117 return events_[index];
118 }
119
120 // Clears all previously dispatched events.
121 void ClearEvents() {
122 events_.clear();
123 }
124
125 private:
126 ScopedVector<ui::Event> events_;
127 Delegate* delegate_;
128
129 DISALLOW_COPY_AND_ASSIGN(MockStickyKeysHandlerDelegate);
130 };
131
132 class StickyKeysTest : public test::AshTestBase,
133 public MockStickyKeysHandlerDelegate::Delegate {
33 protected: 134 protected:
34 StickyKeysTest() 135 StickyKeysTest()
35 : target_(NULL), 136 : target_(NULL),
36 root_window_(NULL) {} 137 root_window_(NULL) {}
37 138
38 virtual void SetUp() OVERRIDE { 139 virtual void SetUp() OVERRIDE {
39 test::AshTestBase::SetUp(); 140 test::AshTestBase::SetUp();
40 141
41 // |target_| owned by root window of shell. It is still safe to delete 142 // |target_| owned by root window of shell. It is still safe to delete
42 // it ourselves. 143 // it ourselves.
43 target_ = CreateTestWindowInShellWithId(0); 144 target_ = CreateTestWindowInShellWithId(0);
44 root_window_ = target_->GetRootWindow(); 145 root_window_ = target_->GetRootWindow();
45 146
46 ui::SetUpTouchPadForTest(kTouchPadDeviceId); 147 ui::SetUpTouchPadForTest(kTouchPadDeviceId);
47 } 148 }
48 149
49 virtual void TearDown() OVERRIDE { 150 virtual void TearDown() OVERRIDE {
50 test::AshTestBase::TearDown(); 151 test::AshTestBase::TearDown();
51 } 152 }
52 153
53 virtual void OnShortcutPressed() { 154 // Overridden from MockStickyKeysHandlerDelegate::Delegate:
155 virtual aura::Window* GetExpectedTarget() OVERRIDE {
156 return target_ ? target_ : root_window_;
157 }
158
159 virtual void OnShortcutPressed() OVERRIDE {
54 if (target_) { 160 if (target_) {
55 delete target_; 161 delete target_;
56 target_ = NULL; 162 target_ = NULL;
57 } 163 }
58 } 164 }
59 165
60 ui::KeyEvent* GenerateKey(ui::EventType type, ui::KeyboardCode code) { 166 ui::KeyEvent* GenerateKey(bool is_key_press, ui::KeyboardCode code) {
61 scoped_xevent_.InitKeyEvent(type, code, 0); 167 scoped_xevent_.InitKeyEvent(
62 ui::KeyEvent* event = new ui::KeyEvent(scoped_xevent_, false); 168 is_key_press ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED,
169 code,
170 0);
171 ui::KeyEvent* event = new ui::KeyEvent(scoped_xevent_, false);
172 ui::Event::DispatcherApi dispatcher(event);
173 dispatcher.set_target(target_);
63 return event; 174 return event;
64 } 175 }
65 176
66 // Creates a mouse event backed by a native XInput2 generic button event. 177 // Creates a mouse event backed by a native XInput2 generic button event.
67 // This is the standard native event on Chromebooks. 178 // This is the standard native event on Chromebooks.
68 ui::MouseEvent* GenerateMouseEvent(ui::EventType type) { 179 ui::MouseEvent* GenerateMouseEvent(bool is_button_press) {
69 return GenerateMouseEventAt(type, gfx::Point()); 180 return GenerateMouseEventAt(is_button_press, gfx::Point());
70 } 181 }
71 182
72 // Creates a mouse event backed by a native XInput2 generic button event. 183 // Creates a mouse event backed by a native XInput2 generic button event.
73 // The |location| should be in physical pixels. 184 // The |location| should be in physical pixels.
74 ui::MouseEvent* GenerateMouseEventAt(ui::EventType type, 185 ui::MouseEvent* GenerateMouseEventAt(bool is_button_press,
75 const gfx::Point& location) { 186 const gfx::Point& location) {
76 scoped_xevent_.InitGenericButtonEvent( 187 scoped_xevent_.InitGenericButtonEvent(
77 kTouchPadDeviceId, 188 kTouchPadDeviceId,
78 type, 189 is_button_press ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED,
79 location, 190 location,
80 0); 191 0);
81 ui::MouseEvent* event = new ui::MouseEvent(scoped_xevent_); 192 ui::MouseEvent* event = new ui::MouseEvent(scoped_xevent_);
193 ui::Event::DispatcherApi dispatcher(event);
194 dispatcher.set_target(target_);
82 return event; 195 return event;
83 } 196 }
84 197
85 ui::MouseWheelEvent* GenerateMouseWheelEvent(int wheel_delta) { 198 ui::MouseWheelEvent* GenerateMouseWheelEvent(int wheel_delta) {
86 EXPECT_NE(0, wheel_delta); 199 EXPECT_NE(0, wheel_delta);
87 scoped_xevent_.InitGenericMouseWheelEvent( 200 scoped_xevent_.InitGenericMouseWheelEvent(
88 kTouchPadDeviceId, wheel_delta, 0); 201 kTouchPadDeviceId, wheel_delta, 0);
89 ui::MouseWheelEvent* event = new ui::MouseWheelEvent(scoped_xevent_); 202 ui::MouseWheelEvent* event = new ui::MouseWheelEvent(scoped_xevent_);
90 ui::Event::DispatcherApi dispatcher(event); 203 ui::Event::DispatcherApi dispatcher(event);
91 dispatcher.set_target(target_); 204 dispatcher.set_target(target_);
(...skipping 22 matching lines...) Expand all
114 0, // x_velocity_ordinal 227 0, // x_velocity_ordinal
115 fling_delta, // y_velocity_ordinal 228 fling_delta, // y_velocity_ordinal
116 is_cancel); // is_cancel 229 is_cancel); // is_cancel
117 ui::ScrollEvent* event = new ui::ScrollEvent(scoped_xevent_); 230 ui::ScrollEvent* event = new ui::ScrollEvent(scoped_xevent_);
118 ui::Event::DispatcherApi dispatcher(event); 231 ui::Event::DispatcherApi dispatcher(event);
119 dispatcher.set_target(target_); 232 dispatcher.set_target(target_);
120 return event; 233 return event;
121 } 234 }
122 235
123 // Creates a synthesized KeyEvent that is not backed by a native event. 236 // Creates a synthesized KeyEvent that is not backed by a native event.
124 ui::KeyEvent* GenerateSynthesizedKeyEvent(ui::EventType type, 237 ui::KeyEvent* GenerateSynthesizedKeyEvent(
125 ui::KeyboardCode code) { 238 bool is_key_press, ui::KeyboardCode code) {
126 return new ui::KeyEvent(type, code, 0, true); 239 ui::KeyEvent* event = new ui::KeyEvent(
240 is_key_press ? ui::ET_KEY_PRESSED : ui::ET_MOUSE_RELEASED,
241 code, 0, true);
242 ui::Event::DispatcherApi dispatcher(event);
243 dispatcher.set_target(target_);
244 return event;
127 } 245 }
128 246
129 // Creates a synthesized MouseEvent that is not backed by a native event. 247 // Creates a synthesized MouseEvent that is not backed by a native event.
130 ui::MouseEvent* GenerateSynthesizedMouseEventAt(ui::EventType event_type, 248 ui::MouseEvent* GenerateSynthesizedMouseEventAt(ui::EventType event_type,
131 const gfx::Point& location) { 249 const gfx::Point& location) {
132 ui::MouseEvent* event = new ui::MouseEvent(event_type, 250 ui::MouseEvent* event = new ui::MouseEvent(event_type,
133 location, 251 location,
134 location, 252 location,
135 ui::EF_LEFT_MOUSE_BUTTON, 253 ui::EF_LEFT_MOUSE_BUTTON,
136 ui::EF_LEFT_MOUSE_BUTTON); 254 ui::EF_LEFT_MOUSE_BUTTON);
137 ui::Event::DispatcherApi dispatcher(event); 255 ui::Event::DispatcherApi dispatcher(event);
138 dispatcher.set_target(target_); 256 dispatcher.set_target(target_);
139 return event; 257 return event;
140 } 258 }
141 259
142 // Creates a synthesized mouse press or release event. 260 // Creates a synthesized mouse press or release event.
143 ui::MouseEvent* GenerateSynthesizedMouseClickEvent( 261 ui::MouseEvent* GenerateSynthesizedMouseClickEvent(
144 ui::EventType type, 262 bool is_button_press,
145 const gfx::Point& location) { 263 const gfx::Point& location) {
146 return GenerateSynthesizedMouseEventAt(type, location); 264 return GenerateSynthesizedMouseEventAt(
265 is_button_press ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED,
266 location);
147 } 267 }
148 268
149 // Creates a synthesized ET_MOUSE_MOVED event. 269 // Creates a synthesized ET_MOUSE_MOVED event.
150 ui::MouseEvent* GenerateSynthesizedMouseMoveEvent( 270 ui::MouseEvent* GenerateSynthesizedMouseMoveEvent(
151 const gfx::Point& location) { 271 const gfx::Point& location) {
152 return GenerateSynthesizedMouseEventAt(ui::ET_MOUSE_MOVED, location); 272 return GenerateSynthesizedMouseEventAt(ui::ET_MOUSE_MOVED, location);
153 } 273 }
154 274
155 // Creates a synthesized MouseWHeel event. 275 // Creates a synthesized MouseWHeel event.
156 ui::MouseWheelEvent* GenerateSynthesizedMouseWheelEvent(int wheel_delta) { 276 ui::MouseWheelEvent* GenerateSynthesizedMouseWheelEvent(int wheel_delta) {
157 scoped_ptr<ui::MouseEvent> mev( 277 scoped_ptr<ui::MouseEvent> mev(
158 GenerateSynthesizedMouseEventAt(ui::ET_MOUSEWHEEL, gfx::Point(0, 0))); 278 GenerateSynthesizedMouseEventAt(ui::ET_MOUSEWHEEL, gfx::Point(0, 0)));
159 ui::MouseWheelEvent* event = new ui::MouseWheelEvent(*mev, 0, wheel_delta); 279 ui::MouseWheelEvent* event = new ui::MouseWheelEvent(*mev, 0, wheel_delta);
160 ui::Event::DispatcherApi dispatcher(event); 280 ui::Event::DispatcherApi dispatcher(event);
161 dispatcher.set_target(target_); 281 dispatcher.set_target(target_);
162 return event; 282 return event;
163 } 283 }
164 284
165 void SendActivateStickyKeyPattern(StickyKeysHandler* handler, 285 void SendActivateStickyKeyPattern(StickyKeysHandler* handler,
166 ui::KeyboardCode key_code) { 286 ui::KeyboardCode key_code) {
167 bool released = false;
168 int down_flags = 0;
169 scoped_ptr<ui::KeyEvent> ev; 287 scoped_ptr<ui::KeyEvent> ev;
170 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, key_code)); 288 ev.reset(GenerateKey(true, key_code));
171 handler->HandleKeyEvent(*ev.get(), key_code, &down_flags, &released); 289 handler->HandleKeyEvent(ev.get());
172 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, key_code)); 290 ev.reset(GenerateKey(false, key_code));
173 handler->HandleKeyEvent(*ev.get(), key_code, &down_flags, &released); 291 handler->HandleKeyEvent(ev.get());
174 } 292 }
175 293
176 bool HandleKeyEvent(const ui::KeyEvent& key_event, 294 void SendActivateStickyKeyPattern(ui::EventProcessor* dispatcher,
177 StickyKeysHandler* handler, 295 ui::KeyboardCode key_code) {
178 int* down, 296 scoped_ptr<ui::KeyEvent> ev;
179 bool* up) { 297 ev.reset(GenerateKey(true, key_code));
180 return handler->HandleKeyEvent(key_event, key_event.key_code(), down, up); 298 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(ev.get());
181 } 299 CHECK(!details.dispatcher_destroyed);
182 300 ev.reset(GenerateKey(false, key_code));
183 int HandleKeyEventForDownFlags(const ui::KeyEvent& key_event, 301 details = dispatcher->OnEventFromSource(ev.get());
184 StickyKeysHandler* handler) { 302 CHECK(!details.dispatcher_destroyed);
185 bool released = false;
186 int down = 0;
187 handler->HandleKeyEvent(key_event, key_event.key_code(), &down, &released);
188 return down;
189 } 303 }
190 304
191 aura::Window* target() { return target_; } 305 aura::Window* target() { return target_; }
192 306
193 private: 307 private:
194 // Owned by root window of shell, but we can still delete |target_| safely. 308 // Owned by root window of shell, but we can still delete |target_| safely.
195 aura::Window* target_; 309 aura::Window* target_;
196 // The root window of |target_|. Not owned. 310 // The root window of |target_|. Not owned.
197 aura::Window* root_window_; 311 aura::Window* root_window_;
198 312
199 // Used to construct the various X events. 313 // Used to construct the various X events.
200 ui::ScopedXI2Event scoped_xevent_; 314 ui::ScopedXI2Event scoped_xevent_;
201 315
202 DISALLOW_COPY_AND_ASSIGN(StickyKeysTest); 316 DISALLOW_COPY_AND_ASSIGN(StickyKeysTest);
203 }; 317 };
204 318
205 TEST_F(StickyKeysTest, BasicOneshotScenarioTest) { 319 TEST_F(StickyKeysTest, BasicOneshotScenarioTest) {
206 scoped_ptr<ui::KeyEvent> ev; 320 scoped_ptr<ui::KeyEvent> ev;
207 StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN); 321 MockStickyKeysHandlerDelegate* mock_delegate =
322 new MockStickyKeysHandlerDelegate(this);
323 StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate);
208 324
209 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 325 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
210 326
211 // By typing Shift key, internal state become ENABLED. 327 // By typing Shift key, internal state become ENABLED.
212 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); 328 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
213 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 329 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
214 330
215 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_A)); 331 ev.reset(GenerateKey(true, ui::VKEY_A));
216 bool released = false; 332 sticky_key.HandleKeyEvent(ev.get());
217 int mod_down_flags = 0; 333
218 HandleKeyEvent(*ev.get(), &sticky_key, &mod_down_flags, &released);
219 // Next keyboard event is shift modified. 334 // Next keyboard event is shift modified.
220 EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN); 335 EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
221 // Modifier release notification happens.
222 EXPECT_TRUE(released);
223 336
224 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_A)); 337 ev.reset(GenerateKey(false, ui::VKEY_A));
225 released = false; 338 sticky_key.HandleKeyEvent(ev.get());
226 mod_down_flags = 0;
227 HandleKeyEvent(*ev.get(), &sticky_key, &mod_down_flags, &released);
228 339
229 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 340 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
230 // Making sure Shift up keyboard event is available. 341 // Making sure Shift up keyboard event is dispatched.
231 scoped_ptr<ui::Event> up_event; 342 ASSERT_EQ(2U, mock_delegate->GetEventCount());
232 ASSERT_EQ(0, sticky_key.GetModifierUpEvent(&up_event)); 343 EXPECT_EQ(ui::ET_KEY_PRESSED, mock_delegate->GetEvent(0)->type());
233 EXPECT_TRUE(up_event.get()); 344 EXPECT_EQ(ui::VKEY_A,
234 EXPECT_EQ(ui::ET_KEY_RELEASED, up_event->type()); 345 static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(0))
346 ->key_code());
347 EXPECT_EQ(ui::ET_KEY_RELEASED, mock_delegate->GetEvent(1)->type());
235 EXPECT_EQ(ui::VKEY_SHIFT, 348 EXPECT_EQ(ui::VKEY_SHIFT,
236 static_cast<const ui::KeyEvent*>(up_event.get())->key_code()); 349 static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(1))
350 ->key_code());
237 351
238 // Enabled state is one shot, so next key event should not be shift modified. 352 // Enabled state is one shot, so next key event should not be shift modified.
239 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_A)); 353 ev.reset(GenerateKey(true, ui::VKEY_A));
240 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 354 sticky_key.HandleKeyEvent(ev.get());
241 EXPECT_FALSE(mod_down_flags & ui::EF_SHIFT_DOWN); 355 EXPECT_FALSE(ev->flags() & ui::EF_SHIFT_DOWN);
242 356
243 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_A)); 357 ev.reset(GenerateKey(false, ui::VKEY_A));
244 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 358 sticky_key.HandleKeyEvent(ev.get());
245 EXPECT_FALSE(mod_down_flags & ui::EF_SHIFT_DOWN); 359 EXPECT_FALSE(ev->flags() & ui::EF_SHIFT_DOWN);
246 } 360 }
247 361
248 TEST_F(StickyKeysTest, BasicLockedScenarioTest) { 362 TEST_F(StickyKeysTest, BasicLockedScenarioTest) {
249 scoped_ptr<ui::KeyEvent> ev; 363 scoped_ptr<ui::KeyEvent> ev;
250 StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN); 364 MockStickyKeysHandlerDelegate* mock_delegate =
365 new MockStickyKeysHandlerDelegate(this);
366 StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate);
251 367
252 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 368 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
253 369
254 // By typing shift key, internal state become ENABLED. 370 // By typing shift key, internal state become ENABLED.
255 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); 371 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
256 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 372 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
257 373
258 // By typing shift key again, internal state become LOCKED. 374 // By typing shift key again, internal state become LOCKED.
259 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); 375 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
260 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 376 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
261 377
262 // All keyboard events including keyUp become shift modified. 378 // All keyboard events including keyUp become shift modified.
263 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_A)); 379 ev.reset(GenerateKey(true, ui::VKEY_A));
264 int mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 380 sticky_key.HandleKeyEvent(ev.get());
265 EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN); 381 EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
266 382
267 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_A)); 383 ev.reset(GenerateKey(false, ui::VKEY_A));
268 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 384 sticky_key.HandleKeyEvent(ev.get());
269 EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN); 385 EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
270 386
271 // Locked state keeps after normal keyboard event. 387 // Locked state keeps after normal keyboard event.
272 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 388 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
273 389
274 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_B)); 390 ev.reset(GenerateKey(true, ui::VKEY_B));
275 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 391 sticky_key.HandleKeyEvent(ev.get());
276 EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN); 392 EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
277 393
278 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_B)); 394 ev.reset(GenerateKey(false, ui::VKEY_B));
279 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 395 sticky_key.HandleKeyEvent(ev.get());
280 EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN); 396 EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
281 397
282 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 398 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
283 399
284 // By typing shift key again, internal state become back to DISABLED. 400 // By typing shift key again, internal state become back to DISABLED.
285 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); 401 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
286 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 402 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
287 } 403 }
288 404
289 TEST_F(StickyKeysTest, NonTargetModifierTest) { 405 TEST_F(StickyKeysTest, NonTargetModifierTest) {
290 scoped_ptr<ui::KeyEvent> ev; 406 scoped_ptr<ui::KeyEvent> ev;
291 StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN); 407 MockStickyKeysHandlerDelegate* mock_delegate =
408 new MockStickyKeysHandlerDelegate(this);
409 StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate);
292 410
293 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 411 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
294 412
295 // Non target modifier key does not affect internal state 413 // Non target modifier key does not affect internal state
296 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_MENU)); 414 ev.reset(GenerateKey(true, ui::VKEY_MENU));
297 int mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 415 sticky_key.HandleKeyEvent(ev.get());
298 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 416 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
299 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
300 417
301 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_MENU)); 418 ev.reset(GenerateKey(false, ui::VKEY_MENU));
302 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 419 sticky_key.HandleKeyEvent(ev.get());
303 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 420 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
304 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
305 421
306 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); 422 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
307 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 423 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
308 424
309 // Non target modifier key does not affect internal state 425 // Non target modifier key does not affect internal state
310 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_MENU)); 426 ev.reset(GenerateKey(true, ui::VKEY_MENU));
311 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 427 sticky_key.HandleKeyEvent(ev.get());
312 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 428 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
313 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
314 429
315 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_MENU)); 430 ev.reset(GenerateKey(false, ui::VKEY_MENU));
316 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 431 sticky_key.HandleKeyEvent(ev.get());
317 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 432 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
318 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
319 433
320 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT); 434 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
321 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 435 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
322 436
323 // Non target modifier key does not affect internal state 437 // Non target modifier key does not affect internal state
324 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_MENU)); 438 ev.reset(GenerateKey(true, ui::VKEY_MENU));
325 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 439 sticky_key.HandleKeyEvent(ev.get());
326 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 440 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
327 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
328 441
329 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_MENU)); 442 ev.reset(GenerateKey(false, ui::VKEY_MENU));
330 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 443 sticky_key.HandleKeyEvent(ev.get());
331 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 444 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
332 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
333 } 445 }
334 446
335 TEST_F(StickyKeysTest, NormalShortcutTest) { 447 TEST_F(StickyKeysTest, NormalShortcutTest) {
336 // Sticky keys should not be enabled if we perform a normal shortcut. 448 // Sticky keys should not be enabled if we perform a normal shortcut.
337 scoped_ptr<ui::KeyEvent> ev; 449 scoped_ptr<ui::KeyEvent> ev;
338 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 450 MockStickyKeysHandlerDelegate* mock_delegate =
451 new MockStickyKeysHandlerDelegate(this);
452 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
339 453
340 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 454 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
341 455
342 // Perform ctrl+n shortcut. 456 // Perform ctrl+n shortcut.
343 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL)); 457 ev.reset(GenerateKey(true, ui::VKEY_CONTROL));
344 int mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 458 sticky_key.HandleKeyEvent(ev.get());
345 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_N)); 459 ev.reset(GenerateKey(true, ui::VKEY_N));
346 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 460 sticky_key.HandleKeyEvent(ev.get());
347 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_N)); 461 ev.reset(GenerateKey(false, ui::VKEY_N));
348 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key); 462 sticky_key.HandleKeyEvent(ev.get());
349 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 463 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
350 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL));
351 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
352 464
353 // Sticky keys should not be enabled afterwards. 465 // Sticky keys should not be enabled afterwards.
466 ev.reset(GenerateKey(false, ui::VKEY_CONTROL));
467 sticky_key.HandleKeyEvent(ev.get());
354 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 468 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
355 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
356
357 // Perform ctrl+n shortcut, releasing ctrl first.
358 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL));
359 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
360 ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_N));
361 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
362 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
363 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL));
364 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
365 ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_N));
366 mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
367
368 // Sticky keys should not be enabled afterwards.
369 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
370 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
371 } 469 }
372 470
373 TEST_F(StickyKeysTest, NormalModifiedClickTest) { 471 TEST_F(StickyKeysTest, NormalModifiedClickTest) {
374 scoped_ptr<ui::KeyEvent> kev; 472 scoped_ptr<ui::KeyEvent> kev;
375 scoped_ptr<ui::MouseEvent> mev; 473 scoped_ptr<ui::MouseEvent> mev;
376 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 474 MockStickyKeysHandlerDelegate* mock_delegate =
475 new MockStickyKeysHandlerDelegate(this);
476 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
377 477
378 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 478 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
379 479
380 // Perform ctrl+click. 480 // Perform ctrl+click.
381 kev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL)); 481 kev.reset(GenerateKey(true, ui::VKEY_CONTROL));
382 int mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 482 sticky_key.HandleKeyEvent(kev.get());
383 mev.reset(GenerateMouseEvent(ui::ET_MOUSE_PRESSED)); 483 mev.reset(GenerateMouseEvent(true));
384 bool released = false; 484 sticky_key.HandleMouseEvent(mev.get());
385 sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released); 485 mev.reset(GenerateMouseEvent(false));
386 mev.reset(GenerateMouseEvent(ui::ET_MOUSE_RELEASED)); 486 sticky_key.HandleMouseEvent(mev.get());
387 sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
388 487
389 // Sticky keys should not be enabled afterwards. 488 // Sticky keys should not be enabled afterwards.
390 kev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL)); 489 kev.reset(GenerateKey(false, ui::VKEY_CONTROL));
391 mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 490 sticky_key.HandleKeyEvent(kev.get());
392 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 491 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
393 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
394 } 492 }
395 493
396 TEST_F(StickyKeysTest, MouseMovedModifierTest) { 494 TEST_F(StickyKeysTest, MouseMovedModifierTest) {
397 scoped_ptr<ui::KeyEvent> kev; 495 scoped_ptr<ui::KeyEvent> kev;
398 scoped_ptr<ui::MouseEvent> mev; 496 scoped_ptr<ui::MouseEvent> mev;
399 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 497 MockStickyKeysHandlerDelegate* mock_delegate =
498 new MockStickyKeysHandlerDelegate(this);
499 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
400 500
401 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 501 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
402 502
403 // Press ctrl and handle mouse move events. 503 // Press ctrl and handle mouse move events.
404 kev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL)); 504 kev.reset(GenerateKey(true, ui::VKEY_CONTROL));
405 int mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 505 sticky_key.HandleKeyEvent(kev.get());
406 mev.reset(GenerateSynthesizedMouseMoveEvent(gfx::Point(0, 0))); 506 mev.reset(GenerateSynthesizedMouseMoveEvent(gfx::Point(0, 0)));
407 bool released = false; 507 sticky_key.HandleMouseEvent(mev.get());
408 sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
409 mev.reset(GenerateSynthesizedMouseMoveEvent(gfx::Point(100, 100))); 508 mev.reset(GenerateSynthesizedMouseMoveEvent(gfx::Point(100, 100)));
410 sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released); 509 sticky_key.HandleMouseEvent(mev.get());
411 510
412 // Sticky keys should be enabled afterwards. 511 // Sticky keys should be enabled afterwards.
413 kev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL)); 512 kev.reset(GenerateKey(false, ui::VKEY_CONTROL));
414 mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 513 sticky_key.HandleKeyEvent(kev.get());
415 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 514 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
416 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
417 } 515 }
418 516
419 TEST_F(StickyKeysTest, NormalModifiedScrollTest) { 517 TEST_F(StickyKeysTest, NormalModifiedScrollTest) {
420 scoped_ptr<ui::KeyEvent> kev; 518 scoped_ptr<ui::KeyEvent> kev;
421 scoped_ptr<ui::ScrollEvent> sev; 519 scoped_ptr<ui::ScrollEvent> sev;
422 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 520 MockStickyKeysHandlerDelegate* mock_delegate =
521 new MockStickyKeysHandlerDelegate(this);
522 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
423 523
424 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 524 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
425 525
426 // Perform ctrl+scroll. 526 // Perform ctrl+scroll.
427 kev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL)); 527 kev.reset(GenerateKey(true, ui::VKEY_CONTROL));
428 int mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
429 sev.reset(GenerateFlingScrollEvent(0, true)); 528 sev.reset(GenerateFlingScrollEvent(0, true));
430 bool released = false; 529 sticky_key.HandleScrollEvent(sev.get());
431 sticky_key.HandleScrollEvent(*sev.get(), &mod_down_flags, &released);
432 sev.reset(GenerateScrollEvent(10)); 530 sev.reset(GenerateScrollEvent(10));
433 sticky_key.HandleScrollEvent(*sev.get(), &mod_down_flags, &released); 531 sticky_key.HandleScrollEvent(sev.get());
434 sev.reset(GenerateFlingScrollEvent(10, false)); 532 sev.reset(GenerateFlingScrollEvent(10, false));
435 sticky_key.HandleScrollEvent(*sev.get(), &mod_down_flags, &released); 533 sticky_key.HandleScrollEvent(sev.get());
436 534
437 // Sticky keys should not be enabled afterwards. 535 // Sticky keys should not be enabled afterwards.
438 kev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL)); 536 kev.reset(GenerateKey(false, ui::VKEY_CONTROL));
439 mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 537 sticky_key.HandleKeyEvent(kev.get());
440 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 538 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
441 EXPECT_EQ(ui::EF_NONE, mod_down_flags);
442 } 539 }
443 540
444 TEST_F(StickyKeysTest, MouseEventOneshot) { 541 TEST_F(StickyKeysTest, MouseEventOneshot) {
445 scoped_ptr<ui::MouseEvent> ev; 542 scoped_ptr<ui::MouseEvent> ev;
446 scoped_ptr<ui::KeyEvent> kev; 543 scoped_ptr<ui::KeyEvent> kev;
447 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 544 MockStickyKeysHandlerDelegate* mock_delegate =
545 new MockStickyKeysHandlerDelegate(this);
546 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
448 547
449 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 548 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
450 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 549 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
451 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 550 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
452 551
453 // We should still be in the ENABLED state until we get the mouse 552 // We should still be in the ENABLED state until we get the mouse
454 // release event. 553 // release event.
455 ev.reset(GenerateMouseEvent(ui::ET_MOUSE_PRESSED)); 554 ev.reset(GenerateMouseEvent(true));
456 bool released = false; 555 sticky_key.HandleMouseEvent(ev.get());
457 int mod_down_flags = 0; 556 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
458 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
459 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
460 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 557 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
461 558
462 ev.reset(GenerateMouseEvent(ui::ET_MOUSE_RELEASED)); 559 ev.reset(GenerateMouseEvent(false));
463 released = false; 560 sticky_key.HandleMouseEvent(ev.get());
464 mod_down_flags = 0; 561 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
465 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
466 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
467 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 562 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
468 563
469 // Making sure modifier key release event is dispatched in the right order. 564 // Making sure modifier key release event is dispatched in the right order.
470 EXPECT_TRUE(released); 565 ASSERT_EQ(2u, mock_delegate->GetEventCount());
471 scoped_ptr<ui::Event> up_event; 566 EXPECT_EQ(ui::ET_MOUSE_RELEASED, mock_delegate->GetEvent(0)->type());
472 ASSERT_EQ(0, sticky_key.GetModifierUpEvent(&up_event)); 567 EXPECT_EQ(ui::ET_KEY_RELEASED, mock_delegate->GetEvent(1)->type());
473 EXPECT_TRUE(up_event.get());
474 EXPECT_EQ(ui::ET_KEY_RELEASED, up_event->type());
475 EXPECT_EQ(ui::VKEY_CONTROL, 568 EXPECT_EQ(ui::VKEY_CONTROL,
476 static_cast<const ui::KeyEvent*>(up_event.get())->key_code()); 569 static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(1))
570 ->key_code());
477 571
478 // Enabled state is one shot, so next click should not be control modified. 572 // Enabled state is one shot, so next click should not be control modified.
479 ev.reset(GenerateMouseEvent(ui::ET_MOUSE_PRESSED)); 573 ev.reset(GenerateMouseEvent(true));
480 released = false; 574 sticky_key.HandleMouseEvent(ev.get());
481 mod_down_flags = 0; 575 EXPECT_FALSE(ev->flags() & ui::EF_CONTROL_DOWN);
482 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
483 EXPECT_FALSE(mod_down_flags & ui::EF_CONTROL_DOWN);
484 576
485 ev.reset(GenerateMouseEvent(ui::ET_MOUSE_RELEASED)); 577 ev.reset(GenerateMouseEvent(false));
486 released = false; 578 sticky_key.HandleMouseEvent(ev.get());
487 mod_down_flags = 0; 579 EXPECT_FALSE(ev->flags() & ui::EF_CONTROL_DOWN);
488 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
489 EXPECT_FALSE(mod_down_flags & ui::EF_CONTROL_DOWN);
490 } 580 }
491 581
492 TEST_F(StickyKeysTest, MouseEventLocked) { 582 TEST_F(StickyKeysTest, MouseEventLocked) {
493 scoped_ptr<ui::MouseEvent> ev; 583 scoped_ptr<ui::MouseEvent> ev;
494 scoped_ptr<ui::KeyEvent> kev; 584 scoped_ptr<ui::KeyEvent> kev;
495 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 585 MockStickyKeysHandlerDelegate* mock_delegate =
586 new MockStickyKeysHandlerDelegate(this);
587 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
496 588
497 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 589 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
498 590
499 // Pressing modifier key twice should make us enter lock state. 591 // Pressing modifier key twice should make us enter lock state.
500 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 592 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
501 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 593 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
502 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 594 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
503 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 595 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
504 596
505 // Mouse events should not disable locked mode. 597 // Mouse events should not disable locked mode.
506 for (int i = 0; i < 3; ++i) { 598 for (int i = 0; i < 3; ++i) {
507 bool released = false; 599 ev.reset(GenerateMouseEvent(true));
508 int mod_down_flags = 0; 600 sticky_key.HandleMouseEvent(ev.get());
509 ev.reset(GenerateMouseEvent(ui::ET_MOUSE_PRESSED)); 601 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
510 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released); 602 ev.reset(GenerateMouseEvent(false));
511 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN); 603 sticky_key.HandleMouseEvent(ev.get());
512 ev.reset(GenerateMouseEvent(ui::ET_MOUSE_RELEASED)); 604 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
513 released = false;
514 mod_down_flags = 0;
515 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
516 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
517 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 605 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
518 } 606 }
519 607
520 // Test with mouse wheel. 608 // Test with mouse wheel.
521 for (int i = 0; i < 3; ++i) { 609 for (int i = 0; i < 3; ++i) {
522 bool released = false;
523 int mod_down_flags = 0;
524 ev.reset(GenerateMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta)); 610 ev.reset(GenerateMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta));
525 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released); 611 sticky_key.HandleMouseEvent(ev.get());
526 ev.reset(GenerateMouseWheelEvent(-ui::MouseWheelEvent::kWheelDelta)); 612 ev.reset(GenerateMouseWheelEvent(-ui::MouseWheelEvent::kWheelDelta));
527 released = false; 613 sticky_key.HandleMouseEvent(ev.get());
528 mod_down_flags = 0; 614 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
529 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
530 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
531 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 615 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
532 } 616 }
533 617
534 // Test mixed case with mouse events and key events. 618 // Test mixed case with mouse events and key events.
535 ev.reset(GenerateMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta)); 619 ev.reset(GenerateMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta));
536 bool released = false; 620 sticky_key.HandleMouseEvent(ev.get());
537 int mod_down_flags = 0; 621 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
538 sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released); 622 kev.reset(GenerateKey(true, ui::VKEY_N));
539 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN); 623 sticky_key.HandleKeyEvent(kev.get());
540 kev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_N)); 624 EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN);
541 mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 625 kev.reset(GenerateKey(false, ui::VKEY_N));
542 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN); 626 sticky_key.HandleKeyEvent(kev.get());
543 mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 627 EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN);
544 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
545 628
546 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 629 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
547 } 630 }
548 631
549 TEST_F(StickyKeysTest, ScrollEventOneshot) { 632 TEST_F(StickyKeysTest, ScrollEventOneshot) {
550 scoped_ptr<ui::ScrollEvent> ev; 633 scoped_ptr<ui::ScrollEvent> ev;
551 scoped_ptr<ui::KeyEvent> kev; 634 scoped_ptr<ui::KeyEvent> kev;
552 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 635 MockStickyKeysHandlerDelegate* mock_delegate =
636 new MockStickyKeysHandlerDelegate(this);
637 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
553 638
554 int scroll_deltas[] = {-10, 10}; 639 int scroll_deltas[] = {-10, 10};
555 for (int i = 0; i < 2; ++i) { 640 for (int i = 0; i < 2; ++i) {
641 mock_delegate->ClearEvents();
642
556 // Enable sticky keys. 643 // Enable sticky keys.
557 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 644 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
558 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 645 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
559 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 646 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
560 647
561 // Test a scroll sequence. Sticky keys should only be disabled at the end 648 // Test a scroll sequence. Sticky keys should only be disabled at the end
562 // of the scroll sequence. Fling cancel event starts the scroll sequence. 649 // of the scroll sequence. Fling cancel event starts the scroll sequence.
563 ev.reset(GenerateFlingScrollEvent(0, true)); 650 ev.reset(GenerateFlingScrollEvent(0, true));
564 bool released = false; 651 sticky_key.HandleScrollEvent(ev.get());
565 int mod_down_flags = 0; 652 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
566 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
567 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
568 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 653 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
569 654
570 // Scrolls should all be modified but not disable sticky keys. 655 // Scrolls should all be modified but not disable sticky keys.
571 for (int j = 0; j < 3; ++j) { 656 for (int j = 0; j < 3; ++j) {
572 ev.reset(GenerateScrollEvent(scroll_deltas[i])); 657 ev.reset(GenerateScrollEvent(scroll_deltas[i]));
573 released = false; 658 sticky_key.HandleScrollEvent(ev.get());
574 mod_down_flags = 0; 659 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
575 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
576 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
577 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 660 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
578 } 661 }
579 662
580 // Fling start event ends scroll sequence. 663 // Fling start event ends scroll sequence.
581 ev.reset(GenerateFlingScrollEvent(scroll_deltas[i], false)); 664 ev.reset(GenerateFlingScrollEvent(scroll_deltas[i], false));
582 released = false; 665 sticky_key.HandleScrollEvent(ev.get());
583 mod_down_flags = 0; 666 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
584 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
585 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
586 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 667 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
587 668
588 scoped_ptr<ui::Event> up_event; 669 ASSERT_EQ(2U, mock_delegate->GetEventCount());
589 EXPECT_TRUE(released); 670 EXPECT_EQ(ui::ET_SCROLL_FLING_START, mock_delegate->GetEvent(0)->type());
590 ASSERT_EQ(0, sticky_key.GetModifierUpEvent(&up_event)); 671 EXPECT_FLOAT_EQ(scroll_deltas[i],
591 EXPECT_TRUE(up_event.get()); 672 static_cast<const ui::ScrollEvent*>(
592 EXPECT_EQ(ui::ET_KEY_RELEASED, up_event->type()); 673 mock_delegate->GetEvent(0))->y_offset());
674 EXPECT_EQ(ui::ET_KEY_RELEASED, mock_delegate->GetEvent(1)->type());
593 EXPECT_EQ(ui::VKEY_CONTROL, 675 EXPECT_EQ(ui::VKEY_CONTROL,
594 static_cast<const ui::KeyEvent*>(up_event.get())->key_code()); 676 static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(1))
677 ->key_code());
595 } 678 }
596 } 679 }
597 680
598 TEST_F(StickyKeysTest, ScrollDirectionChanged) { 681 TEST_F(StickyKeysTest, ScrollDirectionChanged) {
599 scoped_ptr<ui::ScrollEvent> ev; 682 scoped_ptr<ui::ScrollEvent> ev;
600 scoped_ptr<ui::KeyEvent> kev; 683 scoped_ptr<ui::KeyEvent> kev;
601 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 684 MockStickyKeysHandlerDelegate* mock_delegate =
685 new MockStickyKeysHandlerDelegate(this);
686 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
602 687
603 // Test direction change with both boundary value and negative value. 688 // Test direction change with both boundary value and negative value.
604 const int direction_change_values[2] = {0, -10}; 689 const int direction_change_values[2] = {0, -10};
605 for (int i = 0; i < 2; ++i) { 690 for (int i = 0; i < 2; ++i) {
606 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 691 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
607 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 692 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
608 693
609 // Fling cancel starts scroll sequence. 694 // Fling cancel starts scroll sequence.
610 ev.reset(GenerateFlingScrollEvent(0, true)); 695 ev.reset(GenerateFlingScrollEvent(0, true));
611 bool released = false; 696 sticky_key.HandleScrollEvent(ev.get());
612 int mod_down_flags = 0;
613 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
614 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 697 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
615 698
616 // Test that changing directions in a scroll sequence will 699 // Test that changing directions in a scroll sequence will
617 // return sticky keys to DISABLED state. 700 // return sticky keys to DISABLED state.
618 for (int j = 0; j < 3; ++j) { 701 for (int j = 0; j < 3; ++j) {
619 ev.reset(GenerateScrollEvent(10)); 702 ev.reset(GenerateScrollEvent(10));
620 released = false; 703 sticky_key.HandleScrollEvent(ev.get());
621 mod_down_flags = 0; 704 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
622 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
623 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
624 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 705 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
625 } 706 }
626 707
627 ev.reset(GenerateScrollEvent(direction_change_values[i])); 708 ev.reset(GenerateScrollEvent(direction_change_values[i]));
628 released = false; 709 sticky_key.HandleScrollEvent(ev.get());
629 mod_down_flags = 0; 710 EXPECT_FALSE(ev->flags() & ui::EF_CONTROL_DOWN);
630 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
631 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 711 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
632 } 712 }
633 } 713 }
634 714
635 TEST_F(StickyKeysTest, ScrollEventLocked) { 715 TEST_F(StickyKeysTest, ScrollEventLocked) {
636 scoped_ptr<ui::ScrollEvent> ev; 716 scoped_ptr<ui::ScrollEvent> ev;
637 scoped_ptr<ui::KeyEvent> kev; 717 scoped_ptr<ui::KeyEvent> kev;
638 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 718 MockStickyKeysHandlerDelegate* mock_delegate =
719 new MockStickyKeysHandlerDelegate(this);
720 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
639 721
640 // Lock sticky keys. 722 // Lock sticky keys.
641 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 723 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
642 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 724 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
643 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 725 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
644 726
645 // Test scroll events are correctly modified in locked state. 727 // Test scroll events are correctly modified in locked state.
646 for (int i = 0; i < 5; ++i) { 728 for (int i = 0; i < 5; ++i) {
647 // Fling cancel starts scroll sequence. 729 // Fling cancel starts scroll sequence.
648 ev.reset(GenerateFlingScrollEvent(0, true)); 730 ev.reset(GenerateFlingScrollEvent(0, true));
649 bool released = false; 731 sticky_key.HandleScrollEvent(ev.get());
650 int mod_down_flags = 0;
651 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
652 732
653 ev.reset(GenerateScrollEvent(10)); 733 ev.reset(GenerateScrollEvent(10));
654 released = false; 734 sticky_key.HandleScrollEvent(ev.get());
655 mod_down_flags = 0; 735 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
656 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
657 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
658 ev.reset(GenerateScrollEvent(-10)); 736 ev.reset(GenerateScrollEvent(-10));
659 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released); 737 sticky_key.HandleScrollEvent(ev.get());
660 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN); 738 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
661 739
662 // Fling start ends scroll sequence. 740 // Fling start ends scroll sequence.
663 ev.reset(GenerateFlingScrollEvent(-10, false)); 741 ev.reset(GenerateFlingScrollEvent(-10, false));
664 sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released); 742 sticky_key.HandleScrollEvent(ev.get());
665 } 743 }
666 744
667 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state()); 745 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
668 } 746 }
669 747
748 TEST_F(StickyKeysTest, EventTargetDestroyed) {
749 scoped_ptr<ui::KeyEvent> ev;
750 MockStickyKeysHandlerDelegate* mock_delegate =
751 new MockStickyKeysHandlerDelegate(this);
752 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
753
754 target()->Focus();
755
756 // Go into ENABLED state.
757 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
758 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
759 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
760
761 // CTRL+J is a special shortcut that will destroy the event target.
762 ev.reset(GenerateKey(true, ui::VKEY_J));
763 sticky_key.HandleKeyEvent(ev.get());
764 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
765 EXPECT_FALSE(target());
766 }
767
670 TEST_F(StickyKeysTest, SynthesizedEvents) { 768 TEST_F(StickyKeysTest, SynthesizedEvents) {
671 // Non-native, internally generated events should be properly handled 769 // Non-native, internally generated events should be properly handled
672 // by sticky keys. 770 // by sticky keys.
673 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN); 771 MockStickyKeysHandlerDelegate* mock_delegate =
772 new MockStickyKeysHandlerDelegate(this);
773 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
674 774
675 // Test non-native key events. 775 // Test non-native key events.
676 scoped_ptr<ui::KeyEvent> kev; 776 scoped_ptr<ui::KeyEvent> kev;
677 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 777 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
678 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 778 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
679 779
680 kev.reset(GenerateSynthesizedKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_K)); 780 kev.reset(GenerateSynthesizedKeyEvent(true, ui::VKEY_K));
681 int mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 781 sticky_key.HandleKeyEvent(kev.get());
682 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN); 782 EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN);
683 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 783 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
684 784
685 kev.reset(GenerateSynthesizedKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_K)); 785 kev.reset(GenerateSynthesizedKeyEvent(false, ui::VKEY_K));
686 mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key); 786 sticky_key.HandleKeyEvent(kev.get());
687 EXPECT_FALSE(mod_down_flags & ui::EF_CONTROL_DOWN); 787 EXPECT_FALSE(kev->flags() & ui::EF_CONTROL_DOWN);
688 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 788 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
689 789
690 // Test non-native mouse events. 790 // Test non-native mouse events.
691 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); 791 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
692 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 792 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
693 793
694 scoped_ptr<ui::MouseEvent> mev; 794 scoped_ptr<ui::MouseEvent> mev;
695 mev.reset(GenerateSynthesizedMouseClickEvent(ui::ET_MOUSE_PRESSED, 795 mev.reset(GenerateSynthesizedMouseClickEvent(true, gfx::Point(0, 0)));
696 gfx::Point(0, 0))); 796 sticky_key.HandleMouseEvent(mev.get());
697 bool released = false; 797 EXPECT_TRUE(mev->flags() & ui::EF_CONTROL_DOWN);
698 sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
699 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
700 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); 798 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
701 799
702 mev.reset(GenerateSynthesizedMouseClickEvent(ui::ET_MOUSE_RELEASED, 800 mev.reset(GenerateSynthesizedMouseClickEvent(false, gfx::Point(0, 0)));
703 gfx::Point(0, 0))); 801 sticky_key.HandleMouseEvent(mev.get());
704 released = false; 802 EXPECT_TRUE(mev->flags() & ui::EF_CONTROL_DOWN);
705 mod_down_flags = 0;
706 sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
707 EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
708 EXPECT_TRUE(released);
709 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state()); 803 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
710 } 804 }
711 805
806 TEST_F(StickyKeysTest, KeyEventDispatchImpl) {
807 // Test the actual key event dispatch implementation.
808 EventBuffer buffer;
809 ScopedVector<ui::Event> events;
810 ui::EventProcessor* dispatcher =
811 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
812 Shell::GetInstance()->AddPreTargetHandler(&buffer);
813 Shell::GetInstance()->sticky_keys_controller()->Enable(true);
814
815 SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
816 scoped_ptr<ui::KeyEvent> ev;
817 buffer.PopEvents(&events);
818
819 // Test key press event is correctly modified and modifier release
820 // event is sent.
821 ev.reset(GenerateKey(true, ui::VKEY_C));
822 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(ev.get());
823 buffer.PopEvents(&events);
824 EXPECT_EQ(2u, events.size());
825 EXPECT_EQ(ui::ET_KEY_PRESSED, events[0]->type());
826 EXPECT_EQ(ui::VKEY_C, static_cast<ui::KeyEvent*>(events[0])->key_code());
827 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
828 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
829 EXPECT_EQ(ui::VKEY_CONTROL,
830 static_cast<ui::KeyEvent*>(events[1])->key_code());
831
832 // Test key release event is not modified.
833 ev.reset(GenerateKey(false, ui::VKEY_C));
834 details = dispatcher->OnEventFromSource(ev.get());
835 ASSERT_FALSE(details.dispatcher_destroyed);
836 buffer.PopEvents(&events);
837 EXPECT_EQ(1u, events.size());
838 EXPECT_EQ(ui::ET_KEY_RELEASED, events[0]->type());
839 EXPECT_EQ(ui::VKEY_C,
840 static_cast<ui::KeyEvent*>(events[0])->key_code());
841 EXPECT_FALSE(events[0]->flags() & ui::EF_CONTROL_DOWN);
842
843 // Test that synthesized key events are dispatched correctly.
844 SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
845 buffer.PopEvents(&events);
846 scoped_ptr<ui::KeyEvent> kev;
847 kev.reset(GenerateSynthesizedKeyEvent(true, ui::VKEY_K));
848 details = dispatcher->OnEventFromSource(kev.get());
849 ASSERT_FALSE(details.dispatcher_destroyed);
850 buffer.PopEvents(&events);
851 EXPECT_EQ(2u, events.size());
852 EXPECT_EQ(ui::ET_KEY_PRESSED, events[0]->type());
853 EXPECT_EQ(ui::VKEY_K, static_cast<ui::KeyEvent*>(events[0])->key_code());
854 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
855 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
856 EXPECT_EQ(ui::VKEY_CONTROL,
857 static_cast<ui::KeyEvent*>(events[1])->key_code());
858
859 Shell::GetInstance()->RemovePreTargetHandler(&buffer);
860 }
861
862 class StickyKeysMouseDispatchTest
863 : public StickyKeysTest,
864 public ::testing::WithParamInterface<int> {
865 };
866
867 TEST_P(StickyKeysMouseDispatchTest, MouseEventDispatchImpl) {
868 int scale_factor = GetParam();
869 std::ostringstream display_specs;
870 display_specs << "1280x1024*" << scale_factor;
871 UpdateDisplay(display_specs.str());
872
873 EventBuffer buffer;
874 ScopedVector<ui::Event> events;
875 ui::EventProcessor* dispatcher =
876 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
877 Shell::GetInstance()->AddPreTargetHandler(&buffer);
878 Shell::GetInstance()->sticky_keys_controller()->Enable(true);
879
880 scoped_ptr<ui::MouseEvent> ev;
881 SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
882 buffer.PopEvents(&events);
883
884 // Test mouse press event is correctly modified and has correct DIP location.
885 gfx::Point physical_location(400, 400);
886 gfx::Point dip_location(physical_location.x() / scale_factor,
887 physical_location.y() / scale_factor);
888 ev.reset(GenerateMouseEventAt(true, physical_location));
889 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(ev.get());
890 buffer.PopEvents(&events);
891 EXPECT_EQ(1u, events.size());
892 EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0]->type());
893 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
894 EXPECT_EQ(dip_location.ToString(),
895 static_cast<ui::MouseEvent*>(events[0])->location().ToString());
896
897 // Test mouse release event is correctly modified and modifier release
898 // event is sent. The mouse event should have the correct DIP location.
899 ev.reset(GenerateMouseEventAt(false, physical_location));
900 details = dispatcher->OnEventFromSource(ev.get());
901 ASSERT_FALSE(details.dispatcher_destroyed);
902 buffer.PopEvents(&events);
903 EXPECT_EQ(2u, events.size());
904 EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[0]->type());
905 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
906 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
907 EXPECT_EQ(dip_location.ToString(),
908 static_cast<ui::MouseEvent*>(events[0])->location().ToString());
909 EXPECT_EQ(ui::VKEY_CONTROL,
910 static_cast<ui::KeyEvent*>(events[1])->key_code());
911
912 // Test synthesized mouse events are dispatched correctly.
913 SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
914 buffer.PopEvents(&events);
915 ev.reset(GenerateSynthesizedMouseClickEvent(false, physical_location));
916 details = dispatcher->OnEventFromSource(ev.get());
917 ASSERT_FALSE(details.dispatcher_destroyed);
918 buffer.PopEvents(&events);
919 EXPECT_EQ(2u, events.size());
920 EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[0]->type());
921 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
922 EXPECT_EQ(dip_location.ToString(),
923 static_cast<ui::MouseEvent*>(events[0])->location().ToString());
924 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
925 EXPECT_EQ(ui::VKEY_CONTROL,
926 static_cast<ui::KeyEvent*>(events[1])->key_code());
927
928 Shell::GetInstance()->RemovePreTargetHandler(&buffer);
929 }
930
931 TEST_P(StickyKeysMouseDispatchTest, MouseWheelEventDispatchImpl) {
932 int scale_factor = GetParam();
933 std::ostringstream display_specs;
934 display_specs << "1280x1024*" << scale_factor;
935 UpdateDisplay(display_specs.str());
936
937 // Test the actual mouse wheel event dispatch implementation.
938 EventBuffer buffer;
939 ScopedVector<ui::Event> events;
940 ui::EventProcessor* dispatcher =
941 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
942 Shell::GetInstance()->AddPreTargetHandler(&buffer);
943 Shell::GetInstance()->sticky_keys_controller()->Enable(true);
944
945 scoped_ptr<ui::MouseWheelEvent> ev;
946 SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
947 buffer.PopEvents(&events);
948
949 // Test positive mouse wheel event is correctly modified and modifier release
950 // event is sent.
951 ev.reset(GenerateMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta));
952 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(ev.get());
953 ASSERT_FALSE(details.dispatcher_destroyed);
954 buffer.PopEvents(&events);
955 EXPECT_EQ(2u, events.size());
956 EXPECT_TRUE(events[0]->IsMouseWheelEvent());
957 EXPECT_EQ(ui::MouseWheelEvent::kWheelDelta / scale_factor,
958 static_cast<ui::MouseWheelEvent*>(events[0])->y_offset());
959 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
960 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
961 EXPECT_EQ(ui::VKEY_CONTROL,
962 static_cast<ui::KeyEvent*>(events[1])->key_code());
963
964 // Test negative mouse wheel event is correctly modified and modifier release
965 // event is sent.
966 SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
967 buffer.PopEvents(&events);
968
969 ev.reset(GenerateMouseWheelEvent(-ui::MouseWheelEvent::kWheelDelta));
970 details = dispatcher->OnEventFromSource(ev.get());
971 ASSERT_FALSE(details.dispatcher_destroyed);
972 buffer.PopEvents(&events);
973 EXPECT_EQ(2u, events.size());
974 EXPECT_TRUE(events[0]->IsMouseWheelEvent());
975 EXPECT_EQ(-ui::MouseWheelEvent::kWheelDelta / scale_factor,
976 static_cast<ui::MouseWheelEvent*>(events[0])->y_offset());
977 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
978 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
979 EXPECT_EQ(ui::VKEY_CONTROL,
980 static_cast<ui::KeyEvent*>(events[1])->key_code());
981
982 // Test synthesized mouse wheel events are dispatched correctly.
983 SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
984 buffer.PopEvents(&events);
985 ev.reset(
986 GenerateSynthesizedMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta));
987 details = dispatcher->OnEventFromSource(ev.get());
988 ASSERT_FALSE(details.dispatcher_destroyed);
989 buffer.PopEvents(&events);
990 EXPECT_EQ(2u, events.size());
991 EXPECT_TRUE(events[0]->IsMouseWheelEvent());
992 EXPECT_EQ(ui::MouseWheelEvent::kWheelDelta / scale_factor,
993 static_cast<ui::MouseWheelEvent*>(events[0])->y_offset());
994 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
995 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
996 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
997 EXPECT_EQ(ui::VKEY_CONTROL,
998 static_cast<ui::KeyEvent*>(events[1])->key_code());
999
1000 Shell::GetInstance()->RemovePreTargetHandler(&buffer);
1001 }
1002
1003 INSTANTIATE_TEST_CASE_P(DPIScaleFactors,
1004 StickyKeysMouseDispatchTest,
1005 ::testing::Values(1, 2));
1006
712 } // namespace ash 1007 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698