Video Player: Remove unnecessary script file
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller_unittest.cc
blob4fecc24d5b4c18d70b09ef9d15994207e3ee0b43
1 // Copyright (c) 2012 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/accelerators/accelerator_controller.h"
7 #include "ash/accelerators/accelerator_table.h"
8 #include "ash/accessibility_delegate.h"
9 #include "ash/ash_switches.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/ime_control_delegate.h"
12 #include "ash/screen_util.h"
13 #include "ash/shell.h"
14 #include "ash/shell_window_ids.h"
15 #include "ash/system/brightness_control_delegate.h"
16 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
17 #include "ash/system/tray/system_tray_delegate.h"
18 #include "ash/test/ash_test_base.h"
19 #include "ash/test/display_manager_test_api.h"
20 #include "ash/test/test_screenshot_delegate.h"
21 #include "ash/test/test_shell_delegate.h"
22 #include "ash/test/test_volume_control_delegate.h"
23 #include "ash/volume_control_delegate.h"
24 #include "ash/wm/window_state.h"
25 #include "ash/wm/window_util.h"
26 #include "base/command_line.h"
27 #include "ui/aura/client/aura_constants.h"
28 #include "ui/aura/test/event_generator.h"
29 #include "ui/aura/test/test_window_delegate.h"
30 #include "ui/aura/test/test_windows.h"
31 #include "ui/aura/window.h"
32 #include "ui/events/event.h"
33 #include "ui/events/event_processor.h"
34 #include "ui/gfx/screen.h"
35 #include "ui/views/widget/widget.h"
37 #if defined(USE_X11)
38 #include <X11/Xlib.h>
39 #include "ui/events/test/events_test_utils_x11.h"
40 #endif
42 namespace ash {
44 namespace {
46 class TestTarget : public ui::AcceleratorTarget {
47 public:
48 TestTarget() : accelerator_pressed_count_(0), accelerator_repeat_count_(0) {}
49 virtual ~TestTarget() {}
51 int accelerator_pressed_count() const {
52 return accelerator_pressed_count_;
55 int accelerator_repeat_count() const { return accelerator_repeat_count_; }
57 void reset() {
58 accelerator_pressed_count_ = 0;
59 accelerator_repeat_count_ = 0;
62 // Overridden from ui::AcceleratorTarget:
63 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
64 virtual bool CanHandleAccelerators() const OVERRIDE;
66 private:
67 int accelerator_pressed_count_;
68 int accelerator_repeat_count_;
70 DISALLOW_COPY_AND_ASSIGN(TestTarget);
73 class ReleaseAccelerator : public ui::Accelerator {
74 public:
75 ReleaseAccelerator(ui::KeyboardCode keycode, int modifiers)
76 : ui::Accelerator(keycode, modifiers) {
77 set_type(ui::ET_KEY_RELEASED);
81 class DummyBrightnessControlDelegate : public BrightnessControlDelegate {
82 public:
83 explicit DummyBrightnessControlDelegate(bool consume)
84 : consume_(consume),
85 handle_brightness_down_count_(0),
86 handle_brightness_up_count_(0) {
88 virtual ~DummyBrightnessControlDelegate() {}
90 virtual bool HandleBrightnessDown(
91 const ui::Accelerator& accelerator) OVERRIDE {
92 ++handle_brightness_down_count_;
93 last_accelerator_ = accelerator;
94 return consume_;
96 virtual bool HandleBrightnessUp(const ui::Accelerator& accelerator) OVERRIDE {
97 ++handle_brightness_up_count_;
98 last_accelerator_ = accelerator;
99 return consume_;
101 virtual void SetBrightnessPercent(double percent, bool gradual) OVERRIDE {}
102 virtual void GetBrightnessPercent(
103 const base::Callback<void(double)>& callback) OVERRIDE {
104 callback.Run(100.0);
107 int handle_brightness_down_count() const {
108 return handle_brightness_down_count_;
110 int handle_brightness_up_count() const {
111 return handle_brightness_up_count_;
113 const ui::Accelerator& last_accelerator() const {
114 return last_accelerator_;
117 private:
118 const bool consume_;
119 int handle_brightness_down_count_;
120 int handle_brightness_up_count_;
121 ui::Accelerator last_accelerator_;
123 DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate);
126 class DummyImeControlDelegate : public ImeControlDelegate {
127 public:
128 explicit DummyImeControlDelegate(bool consume)
129 : consume_(consume),
130 handle_next_ime_count_(0),
131 handle_previous_ime_count_(0),
132 handle_switch_ime_count_(0) {
134 virtual ~DummyImeControlDelegate() {}
136 virtual void HandleNextIme() OVERRIDE {
137 ++handle_next_ime_count_;
139 virtual bool HandlePreviousIme(const ui::Accelerator& accelerator) OVERRIDE {
140 ++handle_previous_ime_count_;
141 last_accelerator_ = accelerator;
142 return consume_;
144 virtual bool HandleSwitchIme(const ui::Accelerator& accelerator) OVERRIDE {
145 ++handle_switch_ime_count_;
146 last_accelerator_ = accelerator;
147 return consume_;
150 int handle_next_ime_count() const {
151 return handle_next_ime_count_;
153 int handle_previous_ime_count() const {
154 return handle_previous_ime_count_;
156 int handle_switch_ime_count() const {
157 return handle_switch_ime_count_;
159 const ui::Accelerator& last_accelerator() const {
160 return last_accelerator_;
162 virtual ui::Accelerator RemapAccelerator(
163 const ui::Accelerator& accelerator) OVERRIDE {
164 return ui::Accelerator(accelerator);
167 private:
168 const bool consume_;
169 int handle_next_ime_count_;
170 int handle_previous_ime_count_;
171 int handle_switch_ime_count_;
172 ui::Accelerator last_accelerator_;
174 DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate);
177 class DummyKeyboardBrightnessControlDelegate
178 : public KeyboardBrightnessControlDelegate {
179 public:
180 explicit DummyKeyboardBrightnessControlDelegate(bool consume)
181 : consume_(consume),
182 handle_keyboard_brightness_down_count_(0),
183 handle_keyboard_brightness_up_count_(0) {
185 virtual ~DummyKeyboardBrightnessControlDelegate() {}
187 virtual bool HandleKeyboardBrightnessDown(
188 const ui::Accelerator& accelerator) OVERRIDE {
189 ++handle_keyboard_brightness_down_count_;
190 last_accelerator_ = accelerator;
191 return consume_;
194 virtual bool HandleKeyboardBrightnessUp(
195 const ui::Accelerator& accelerator) OVERRIDE {
196 ++handle_keyboard_brightness_up_count_;
197 last_accelerator_ = accelerator;
198 return consume_;
201 int handle_keyboard_brightness_down_count() const {
202 return handle_keyboard_brightness_down_count_;
205 int handle_keyboard_brightness_up_count() const {
206 return handle_keyboard_brightness_up_count_;
209 const ui::Accelerator& last_accelerator() const {
210 return last_accelerator_;
213 private:
214 const bool consume_;
215 int handle_keyboard_brightness_down_count_;
216 int handle_keyboard_brightness_up_count_;
217 ui::Accelerator last_accelerator_;
219 DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate);
222 bool TestTarget::AcceleratorPressed(const ui::Accelerator& accelerator) {
223 if (accelerator.IsRepeat())
224 ++accelerator_repeat_count_;
225 else
226 ++accelerator_pressed_count_;
227 return true;
230 bool TestTarget::CanHandleAccelerators() const {
231 return true;
234 } // namespace
236 class AcceleratorControllerTest : public test::AshTestBase {
237 public:
238 AcceleratorControllerTest() {}
239 virtual ~AcceleratorControllerTest() {}
241 protected:
242 void EnableInternalDisplay() {
243 test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
244 SetFirstDisplayAsInternalDisplay();
247 static AcceleratorController* GetController();
249 // Several functions to access ExitWarningHandler (as friend).
250 static void StubForTest(ExitWarningHandler* ewh) {
251 ewh->stub_timer_for_test_ = true;
253 static void Reset(ExitWarningHandler* ewh) {
254 ewh->state_ = ExitWarningHandler::IDLE;
256 static void SimulateTimerExpired(ExitWarningHandler* ewh) {
257 ewh->TimerAction();
259 static bool is_ui_shown(ExitWarningHandler* ewh) {
260 return !!ewh->widget_;
262 static bool is_idle(ExitWarningHandler* ewh) {
263 return ewh->state_ == ExitWarningHandler::IDLE;
265 static bool is_exiting(ExitWarningHandler* ewh) {
266 return ewh->state_ == ExitWarningHandler::EXITING;
269 private:
270 DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest);
273 AcceleratorController* AcceleratorControllerTest::GetController() {
274 return Shell::GetInstance()->accelerator_controller();
277 #if !defined(OS_WIN)
278 // Double press of exit shortcut => exiting
279 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) {
280 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
281 ui::Accelerator release(press);
282 release.set_type(ui::ET_KEY_RELEASED);
283 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
284 ASSERT_TRUE(!!ewh);
285 StubForTest(ewh);
286 EXPECT_TRUE(is_idle(ewh));
287 EXPECT_FALSE(is_ui_shown(ewh));
288 EXPECT_TRUE(GetController()->Process(press));
289 EXPECT_FALSE(GetController()->Process(release));
290 EXPECT_FALSE(is_idle(ewh));
291 EXPECT_TRUE(is_ui_shown(ewh));
292 EXPECT_TRUE(GetController()->Process(press)); // second press before timer.
293 EXPECT_FALSE(GetController()->Process(release));
294 SimulateTimerExpired(ewh);
295 EXPECT_TRUE(is_exiting(ewh));
296 EXPECT_FALSE(is_ui_shown(ewh));
297 Reset(ewh);
300 // Single press of exit shortcut before timer => idle
301 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) {
302 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
303 ui::Accelerator release(press);
304 release.set_type(ui::ET_KEY_RELEASED);
305 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
306 ASSERT_TRUE(!!ewh);
307 StubForTest(ewh);
308 EXPECT_TRUE(is_idle(ewh));
309 EXPECT_FALSE(is_ui_shown(ewh));
310 EXPECT_TRUE(GetController()->Process(press));
311 EXPECT_FALSE(GetController()->Process(release));
312 EXPECT_FALSE(is_idle(ewh));
313 EXPECT_TRUE(is_ui_shown(ewh));
314 SimulateTimerExpired(ewh);
315 EXPECT_TRUE(is_idle(ewh));
316 EXPECT_FALSE(is_ui_shown(ewh));
317 Reset(ewh);
320 // Shutdown ash with exit warning bubble open should not crash.
321 TEST_F(AcceleratorControllerTest, LingeringExitWarningBubble) {
322 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
323 ASSERT_TRUE(!!ewh);
324 StubForTest(ewh);
326 // Trigger once to show the bubble.
327 ewh->HandleAccelerator();
328 EXPECT_FALSE(is_idle(ewh));
329 EXPECT_TRUE(is_ui_shown(ewh));
331 // Exit ash and there should be no crash
333 #endif // !defined(OS_WIN)
335 TEST_F(AcceleratorControllerTest, Register) {
336 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
337 TestTarget target;
338 GetController()->Register(accelerator_a, &target);
340 // The registered accelerator is processed.
341 EXPECT_TRUE(GetController()->Process(accelerator_a));
342 EXPECT_EQ(1, target.accelerator_pressed_count());
345 TEST_F(AcceleratorControllerTest, RegisterMultipleTarget) {
346 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
347 TestTarget target1;
348 GetController()->Register(accelerator_a, &target1);
349 TestTarget target2;
350 GetController()->Register(accelerator_a, &target2);
352 // If multiple targets are registered with the same accelerator, the target
353 // registered later processes the accelerator.
354 EXPECT_TRUE(GetController()->Process(accelerator_a));
355 EXPECT_EQ(0, target1.accelerator_pressed_count());
356 EXPECT_EQ(1, target2.accelerator_pressed_count());
359 TEST_F(AcceleratorControllerTest, Unregister) {
360 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
361 TestTarget target;
362 GetController()->Register(accelerator_a, &target);
363 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
364 GetController()->Register(accelerator_b, &target);
366 // Unregistering a different accelerator does not affect the other
367 // accelerator.
368 GetController()->Unregister(accelerator_b, &target);
369 EXPECT_TRUE(GetController()->Process(accelerator_a));
370 EXPECT_EQ(1, target.accelerator_pressed_count());
372 // The unregistered accelerator is no longer processed.
373 target.reset();
374 GetController()->Unregister(accelerator_a, &target);
375 EXPECT_FALSE(GetController()->Process(accelerator_a));
376 EXPECT_EQ(0, target.accelerator_pressed_count());
379 TEST_F(AcceleratorControllerTest, UnregisterAll) {
380 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
381 TestTarget target1;
382 GetController()->Register(accelerator_a, &target1);
383 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
384 GetController()->Register(accelerator_b, &target1);
385 const ui::Accelerator accelerator_c(ui::VKEY_C, ui::EF_NONE);
386 TestTarget target2;
387 GetController()->Register(accelerator_c, &target2);
388 GetController()->UnregisterAll(&target1);
390 // All the accelerators registered for |target1| are no longer processed.
391 EXPECT_FALSE(GetController()->Process(accelerator_a));
392 EXPECT_FALSE(GetController()->Process(accelerator_b));
393 EXPECT_EQ(0, target1.accelerator_pressed_count());
395 // UnregisterAll with a different target does not affect the other target.
396 EXPECT_TRUE(GetController()->Process(accelerator_c));
397 EXPECT_EQ(1, target2.accelerator_pressed_count());
400 TEST_F(AcceleratorControllerTest, Process) {
401 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
402 TestTarget target1;
403 GetController()->Register(accelerator_a, &target1);
405 // The registered accelerator is processed.
406 EXPECT_TRUE(GetController()->Process(accelerator_a));
407 EXPECT_EQ(1, target1.accelerator_pressed_count());
409 // The non-registered accelerator is not processed.
410 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
411 EXPECT_FALSE(GetController()->Process(accelerator_b));
414 TEST_F(AcceleratorControllerTest, IsRegistered) {
415 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
416 const ui::Accelerator accelerator_shift_a(ui::VKEY_A, ui::EF_SHIFT_DOWN);
417 TestTarget target;
418 GetController()->Register(accelerator_a, &target);
419 EXPECT_TRUE(GetController()->IsRegistered(accelerator_a));
420 EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a));
421 GetController()->UnregisterAll(&target);
422 EXPECT_FALSE(GetController()->IsRegistered(accelerator_a));
425 TEST_F(AcceleratorControllerTest, WindowSnap) {
426 scoped_ptr<aura::Window> window(
427 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
428 const ui::Accelerator dummy;
430 wm::WindowState* window_state = wm::GetWindowState(window.get());
432 window_state->Activate();
435 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
436 gfx::Rect expected_bounds = wm::GetDefaultLeftSnappedWindowBoundsInParent(
437 window.get());
438 EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString());
441 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
442 gfx::Rect expected_bounds = wm::GetDefaultRightSnappedWindowBoundsInParent(
443 window.get());
444 EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString());
447 gfx::Rect normal_bounds = window_state->GetRestoreBoundsInParent();
449 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
450 EXPECT_TRUE(window_state->IsMaximized());
451 EXPECT_NE(normal_bounds.ToString(), window->bounds().ToString());
453 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
454 EXPECT_FALSE(window_state->IsMaximized());
455 // Window gets restored to its restore bounds since side-maximized state
456 // is treated as a "maximized" state.
457 EXPECT_EQ(normal_bounds.ToString(), window->bounds().ToString());
459 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
460 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
461 EXPECT_FALSE(window_state->IsMaximized());
463 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
464 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
465 EXPECT_FALSE(window_state->IsMaximized());
467 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
468 EXPECT_TRUE(window_state->IsMaximized());
469 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
470 EXPECT_FALSE(window_state->IsMaximized());
471 EXPECT_TRUE(window_state->IsMinimized());
472 window_state->Restore();
473 window_state->Activate();
476 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
477 EXPECT_TRUE(window_state->IsMinimized());
481 TEST_F(AcceleratorControllerTest, CenterWindowAccelerator) {
482 scoped_ptr<aura::Window> window(
483 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
484 const ui::Accelerator dummy;
485 wm::WindowState* window_state = wm::GetWindowState(window.get());
486 window_state->Activate();
488 // Center the window using accelerator.
489 GetController()->PerformAction(WINDOW_POSITION_CENTER, dummy);
490 gfx::Rect work_area =
491 Shell::GetScreen()->GetDisplayNearestWindow(window.get()).work_area();
492 gfx::Rect bounds = window->GetBoundsInScreen();
493 EXPECT_NEAR(bounds.x() - work_area.x(),
494 work_area.right() - bounds.right(),
496 EXPECT_NEAR(bounds.y() - work_area.y(),
497 work_area.bottom() - bounds.bottom(),
500 // Add the window to docked container and try to center it.
501 window->SetBounds(gfx::Rect(0, 0, 20, 20));
502 aura::Window* docked_container = Shell::GetContainer(
503 window->GetRootWindow(), kShellWindowId_DockedContainer);
504 docked_container->AddChild(window.get());
505 gfx::Rect docked_bounds = window->GetBoundsInScreen();
506 GetController()->PerformAction(WINDOW_POSITION_CENTER, dummy);
507 // It should not get centered and should remain docked.
508 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
509 EXPECT_EQ(docked_bounds.ToString(), window->GetBoundsInScreen().ToString());
512 TEST_F(AcceleratorControllerTest, AutoRepeat) {
513 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_CONTROL_DOWN);
514 accelerator_a.set_type(ui::ET_KEY_PRESSED);
515 TestTarget target_a;
516 GetController()->Register(accelerator_a, &target_a);
517 ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_CONTROL_DOWN);
518 accelerator_b.set_type(ui::ET_KEY_PRESSED);
519 TestTarget target_b;
520 GetController()->Register(accelerator_b, &target_b);
522 aura::test::EventGenerator& generator = GetEventGenerator();
523 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
524 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
526 EXPECT_EQ(1, target_a.accelerator_pressed_count());
527 EXPECT_EQ(0, target_a.accelerator_repeat_count());
529 // Long press should generate one
530 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
531 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
532 EXPECT_EQ(2, target_a.accelerator_pressed_count());
533 EXPECT_EQ(1, target_a.accelerator_repeat_count());
534 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
535 EXPECT_EQ(2, target_a.accelerator_pressed_count());
536 EXPECT_EQ(2, target_a.accelerator_repeat_count());
537 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
538 EXPECT_EQ(2, target_a.accelerator_pressed_count());
539 EXPECT_EQ(2, target_a.accelerator_repeat_count());
541 // Long press was intercepted by another key press.
542 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
543 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
544 generator.PressKey(ui::VKEY_B, ui::EF_CONTROL_DOWN);
545 generator.ReleaseKey(ui::VKEY_B, ui::EF_CONTROL_DOWN);
546 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
547 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
548 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
550 EXPECT_EQ(1, target_b.accelerator_pressed_count());
551 EXPECT_EQ(0, target_b.accelerator_repeat_count());
552 EXPECT_EQ(4, target_a.accelerator_pressed_count());
553 EXPECT_EQ(4, target_a.accelerator_repeat_count());
556 TEST_F(AcceleratorControllerTest, Previous) {
557 aura::test::EventGenerator& generator = GetEventGenerator();
558 generator.PressKey(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
559 generator.ReleaseKey(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
561 EXPECT_EQ(ui::VKEY_VOLUME_MUTE,
562 GetController()->previous_accelerator_for_test().key_code());
563 EXPECT_EQ(ui::EF_NONE,
564 GetController()->previous_accelerator_for_test().modifiers());
566 generator.PressKey(ui::VKEY_TAB, ui::EF_CONTROL_DOWN);
567 generator.ReleaseKey(ui::VKEY_TAB, ui::EF_CONTROL_DOWN);
569 EXPECT_EQ(ui::VKEY_TAB,
570 GetController()->previous_accelerator_for_test().key_code());
571 EXPECT_EQ(ui::EF_CONTROL_DOWN,
572 GetController()->previous_accelerator_for_test().modifiers());
575 TEST_F(AcceleratorControllerTest, DontRepeatToggleFullscreen) {
576 const AcceleratorData accelerators[] = {
577 {true, ui::VKEY_J, ui::EF_ALT_DOWN, TOGGLE_FULLSCREEN},
578 {true, ui::VKEY_K, ui::EF_ALT_DOWN, TOGGLE_FULLSCREEN},
580 GetController()->RegisterAccelerators(accelerators, arraysize(accelerators));
582 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
583 params.context = CurrentContext();
584 params.bounds = gfx::Rect(5, 5, 20, 20);
585 views::Widget* widget = new views::Widget;
586 widget->Init(params);
587 widget->Show();
588 widget->Activate();
589 widget->GetNativeView()->SetProperty(aura::client::kCanMaximizeKey, true);
591 aura::test::EventGenerator& generator = GetEventGenerator();
592 wm::WindowState* window_state = wm::GetWindowState(widget->GetNativeView());
594 // Toggling not suppressed.
595 generator.PressKey(ui::VKEY_J, ui::EF_ALT_DOWN);
596 EXPECT_TRUE(window_state->IsFullscreen());
598 // The same accelerator - toggling suppressed.
599 generator.PressKey(ui::VKEY_J, ui::EF_ALT_DOWN | ui::EF_IS_REPEAT);
600 EXPECT_TRUE(window_state->IsFullscreen());
602 // Different accelerator.
603 generator.PressKey(ui::VKEY_K, ui::EF_ALT_DOWN);
604 EXPECT_FALSE(window_state->IsFullscreen());
607 // TODO(oshima): Fix this test to use EventGenerator.
608 #if defined(OS_WIN)
609 // crbug.com/317592
610 #define MAYBE_ProcessOnce DISABLED_ProcessOnce
611 #else
612 #define MAYBE_ProcessOnce ProcessOnce
613 #endif
615 #if defined(OS_WIN) || defined(USE_X11)
616 TEST_F(AcceleratorControllerTest, MAYBE_ProcessOnce) {
617 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
618 TestTarget target;
619 GetController()->Register(accelerator_a, &target);
621 // The accelerator is processed only once.
622 ui::EventProcessor* dispatcher =
623 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
624 #if defined(OS_WIN)
625 MSG msg1 = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 };
626 ui::KeyEvent key_event1(msg1, false);
627 key_event1.SetTranslated(true);
628 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1);
629 EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed);
631 MSG msg2 = { NULL, WM_CHAR, L'A', 0 };
632 ui::KeyEvent key_event2(msg2, true);
633 key_event2.SetTranslated(true);
634 details = dispatcher->OnEventFromSource(&key_event2);
635 EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed);
637 MSG msg3 = { NULL, WM_KEYUP, ui::VKEY_A, 0 };
638 ui::KeyEvent key_event3(msg3, false);
639 key_event3.SetTranslated(true);
640 details = dispatcher->OnEventFromSource(&key_event3);
641 EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed);
642 #elif defined(USE_X11)
643 ui::ScopedXI2Event key_event;
644 key_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
645 ui::KeyEvent key_event1(key_event, false);
646 key_event1.SetTranslated(true);
647 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1);
648 EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed);
650 ui::KeyEvent key_event2(key_event, true);
651 key_event2.SetTranslated(true);
652 details = dispatcher->OnEventFromSource(&key_event2);
653 EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed);
655 key_event.InitKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_A, 0);
656 ui::KeyEvent key_event3(key_event, false);
657 key_event3.SetTranslated(true);
658 details = dispatcher->OnEventFromSource(&key_event3);
659 EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed);
660 #endif
661 EXPECT_EQ(1, target.accelerator_pressed_count());
663 #endif
665 TEST_F(AcceleratorControllerTest, GlobalAccelerators) {
666 // CycleBackward
667 EXPECT_TRUE(GetController()->Process(
668 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
669 // CycleForward
670 EXPECT_TRUE(
671 GetController()->Process(ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
672 // CycleLinear
673 EXPECT_TRUE(GetController()->Process(
674 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE)));
676 #if defined(OS_CHROMEOS)
677 // Take screenshot / partial screenshot
678 // True should always be returned regardless of the existence of the delegate.
680 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
681 delegate->set_can_take_screenshot(false);
682 EXPECT_TRUE(GetController()->Process(
683 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
684 EXPECT_TRUE(
685 GetController()->Process(ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
686 EXPECT_TRUE(GetController()->Process(ui::Accelerator(
687 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
689 delegate->set_can_take_screenshot(true);
690 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
691 EXPECT_TRUE(GetController()->Process(
692 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
693 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
694 EXPECT_TRUE(
695 GetController()->Process(ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
696 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
697 EXPECT_TRUE(GetController()->Process(ui::Accelerator(
698 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
699 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
701 #endif
702 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
703 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
704 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
706 TestVolumeControlDelegate* delegate =
707 new TestVolumeControlDelegate(false);
708 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
709 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
710 EXPECT_EQ(0, delegate->handle_volume_mute_count());
711 EXPECT_FALSE(GetController()->Process(volume_mute));
712 EXPECT_EQ(1, delegate->handle_volume_mute_count());
713 EXPECT_EQ(volume_mute, delegate->last_accelerator());
714 EXPECT_EQ(0, delegate->handle_volume_down_count());
715 EXPECT_FALSE(GetController()->Process(volume_down));
716 EXPECT_EQ(1, delegate->handle_volume_down_count());
717 EXPECT_EQ(volume_down, delegate->last_accelerator());
718 EXPECT_EQ(0, delegate->handle_volume_up_count());
719 EXPECT_FALSE(GetController()->Process(volume_up));
720 EXPECT_EQ(1, delegate->handle_volume_up_count());
721 EXPECT_EQ(volume_up, delegate->last_accelerator());
724 TestVolumeControlDelegate* delegate = new TestVolumeControlDelegate(true);
725 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
726 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
727 EXPECT_EQ(0, delegate->handle_volume_mute_count());
728 EXPECT_TRUE(GetController()->Process(volume_mute));
729 EXPECT_EQ(1, delegate->handle_volume_mute_count());
730 EXPECT_EQ(volume_mute, delegate->last_accelerator());
731 EXPECT_EQ(0, delegate->handle_volume_down_count());
732 EXPECT_TRUE(GetController()->Process(volume_down));
733 EXPECT_EQ(1, delegate->handle_volume_down_count());
734 EXPECT_EQ(volume_down, delegate->last_accelerator());
735 EXPECT_EQ(0, delegate->handle_volume_up_count());
736 EXPECT_TRUE(GetController()->Process(volume_up));
737 EXPECT_EQ(1, delegate->handle_volume_up_count());
738 EXPECT_EQ(volume_up, delegate->last_accelerator());
740 #if defined(OS_CHROMEOS)
741 // Brightness
742 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
743 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
744 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
746 DummyBrightnessControlDelegate* delegate =
747 new DummyBrightnessControlDelegate(false);
748 GetController()->SetBrightnessControlDelegate(
749 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
750 EXPECT_EQ(0, delegate->handle_brightness_down_count());
751 EXPECT_FALSE(GetController()->Process(brightness_down));
752 EXPECT_EQ(1, delegate->handle_brightness_down_count());
753 EXPECT_EQ(brightness_down, delegate->last_accelerator());
754 EXPECT_EQ(0, delegate->handle_brightness_up_count());
755 EXPECT_FALSE(GetController()->Process(brightness_up));
756 EXPECT_EQ(1, delegate->handle_brightness_up_count());
757 EXPECT_EQ(brightness_up, delegate->last_accelerator());
760 DummyBrightnessControlDelegate* delegate =
761 new DummyBrightnessControlDelegate(true);
762 GetController()->SetBrightnessControlDelegate(
763 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
764 EXPECT_EQ(0, delegate->handle_brightness_down_count());
765 EXPECT_TRUE(GetController()->Process(brightness_down));
766 EXPECT_EQ(1, delegate->handle_brightness_down_count());
767 EXPECT_EQ(brightness_down, delegate->last_accelerator());
768 EXPECT_EQ(0, delegate->handle_brightness_up_count());
769 EXPECT_TRUE(GetController()->Process(brightness_up));
770 EXPECT_EQ(1, delegate->handle_brightness_up_count());
771 EXPECT_EQ(brightness_up, delegate->last_accelerator());
774 // Keyboard brightness
775 const ui::Accelerator alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN,
776 ui::EF_ALT_DOWN);
777 const ui::Accelerator alt_brightness_up(ui::VKEY_BRIGHTNESS_UP,
778 ui::EF_ALT_DOWN);
780 EXPECT_TRUE(GetController()->Process(alt_brightness_down));
781 EXPECT_TRUE(GetController()->Process(alt_brightness_up));
782 DummyKeyboardBrightnessControlDelegate* delegate =
783 new DummyKeyboardBrightnessControlDelegate(false);
784 GetController()->SetKeyboardBrightnessControlDelegate(
785 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
786 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
787 EXPECT_FALSE(GetController()->Process(alt_brightness_down));
788 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
789 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
790 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
791 EXPECT_FALSE(GetController()->Process(alt_brightness_up));
792 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
793 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
796 DummyKeyboardBrightnessControlDelegate* delegate =
797 new DummyKeyboardBrightnessControlDelegate(true);
798 GetController()->SetKeyboardBrightnessControlDelegate(
799 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
800 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
801 EXPECT_TRUE(GetController()->Process(alt_brightness_down));
802 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
803 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
804 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
805 EXPECT_TRUE(GetController()->Process(alt_brightness_up));
806 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
807 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
809 #endif
811 #if !defined(NDEBUG)
812 // ToggleDesktopBackgroundMode
813 EXPECT_TRUE(GetController()->Process(
814 ui::Accelerator(ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)));
815 #if !defined(OS_LINUX)
816 // ToggleDesktopFullScreen (not implemented yet on Linux)
817 EXPECT_TRUE(GetController()->Process(
818 ui::Accelerator(ui::VKEY_F11, ui::EF_CONTROL_DOWN)));
819 #endif // OS_LINUX
820 #endif // !NDEBUG
822 #if !defined(OS_WIN)
823 // Exit
824 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
825 ASSERT_TRUE(!!ewh);
826 StubForTest(ewh);
827 EXPECT_TRUE(is_idle(ewh));
828 EXPECT_FALSE(is_ui_shown(ewh));
829 EXPECT_TRUE(GetController()->Process(
830 ui::Accelerator(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
831 EXPECT_FALSE(is_idle(ewh));
832 EXPECT_TRUE(is_ui_shown(ewh));
833 SimulateTimerExpired(ewh);
834 EXPECT_TRUE(is_idle(ewh));
835 EXPECT_FALSE(is_ui_shown(ewh));
836 Reset(ewh);
837 #endif
839 // New tab
840 EXPECT_TRUE(GetController()->Process(
841 ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN)));
843 // New incognito window
844 EXPECT_TRUE(GetController()->Process(
845 ui::Accelerator(ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
847 // New window
848 EXPECT_TRUE(GetController()->Process(
849 ui::Accelerator(ui::VKEY_N, ui::EF_CONTROL_DOWN)));
851 // Restore tab
852 EXPECT_TRUE(GetController()->Process(
853 ui::Accelerator(ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
855 // Show task manager
856 EXPECT_TRUE(GetController()->Process(
857 ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN)));
859 #if defined(OS_CHROMEOS)
860 // Open file manager
861 EXPECT_TRUE(GetController()->Process(
862 ui::Accelerator(ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
864 // Lock screen
865 // NOTE: Accelerators that do not work on the lock screen need to be
866 // tested before the sequence below is invoked because it causes a side
867 // effect of locking the screen.
868 EXPECT_TRUE(GetController()->Process(
869 ui::Accelerator(ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
870 #endif
873 TEST_F(AcceleratorControllerTest, GlobalAcceleratorsToggleAppList) {
874 AccessibilityDelegate* delegate =
875 ash::Shell::GetInstance()->accessibility_delegate();
876 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
878 // The press event should not open the AppList, the release should instead.
879 EXPECT_FALSE(
880 GetController()->Process(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
881 EXPECT_EQ(ui::VKEY_LWIN,
882 GetController()->previous_accelerator_for_test().key_code());
884 EXPECT_TRUE(
885 GetController()->Process(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
886 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
888 // When spoken feedback is on, the AppList should not toggle.
889 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
890 EXPECT_FALSE(
891 GetController()->Process(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
892 EXPECT_FALSE(
893 GetController()->Process(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
894 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
895 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
897 EXPECT_FALSE(
898 GetController()->Process(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
899 EXPECT_TRUE(
900 GetController()->Process(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
901 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
903 // When spoken feedback is on, the AppList should not toggle.
904 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
905 EXPECT_FALSE(
906 GetController()->Process(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
907 EXPECT_FALSE(
908 GetController()->Process(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
909 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
910 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
913 TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) {
914 // Test IME shortcuts.
916 const ui::Accelerator control_space(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
917 const ui::Accelerator convert(ui::VKEY_CONVERT, ui::EF_NONE);
918 const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, ui::EF_NONE);
919 const ui::Accelerator wide_half_1(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE);
920 const ui::Accelerator wide_half_2(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE);
921 const ui::Accelerator hangul(ui::VKEY_HANGUL, ui::EF_NONE);
922 EXPECT_FALSE(GetController()->Process(control_space));
923 EXPECT_FALSE(GetController()->Process(convert));
924 EXPECT_FALSE(GetController()->Process(non_convert));
925 EXPECT_FALSE(GetController()->Process(wide_half_1));
926 EXPECT_FALSE(GetController()->Process(wide_half_2));
927 EXPECT_FALSE(GetController()->Process(hangul));
928 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
929 GetController()->SetImeControlDelegate(
930 scoped_ptr<ImeControlDelegate>(delegate).Pass());
931 EXPECT_EQ(0, delegate->handle_previous_ime_count());
932 EXPECT_TRUE(GetController()->Process(control_space));
933 EXPECT_EQ(1, delegate->handle_previous_ime_count());
934 EXPECT_EQ(0, delegate->handle_switch_ime_count());
935 EXPECT_TRUE(GetController()->Process(convert));
936 EXPECT_EQ(1, delegate->handle_switch_ime_count());
937 EXPECT_TRUE(GetController()->Process(non_convert));
938 EXPECT_EQ(2, delegate->handle_switch_ime_count());
939 EXPECT_TRUE(GetController()->Process(wide_half_1));
940 EXPECT_EQ(3, delegate->handle_switch_ime_count());
941 EXPECT_TRUE(GetController()->Process(wide_half_2));
942 EXPECT_EQ(4, delegate->handle_switch_ime_count());
943 EXPECT_TRUE(GetController()->Process(hangul));
944 EXPECT_EQ(5, delegate->handle_switch_ime_count());
947 // Test IME shortcuts that are triggered on key release.
949 const ui::Accelerator shift_alt_press(ui::VKEY_MENU,
950 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
951 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
952 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT,
953 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
954 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
956 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
957 GetController()->SetImeControlDelegate(
958 scoped_ptr<ImeControlDelegate>(delegate).Pass());
959 EXPECT_EQ(0, delegate->handle_next_ime_count());
960 EXPECT_FALSE(GetController()->Process(shift_alt_press));
961 EXPECT_FALSE(GetController()->Process(shift_alt));
962 EXPECT_EQ(1, delegate->handle_next_ime_count());
963 EXPECT_FALSE(GetController()->Process(alt_shift_press));
964 EXPECT_FALSE(GetController()->Process(alt_shift));
965 EXPECT_EQ(2, delegate->handle_next_ime_count());
967 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
968 // released.
969 const ui::Accelerator shift_alt_x_press(
970 ui::VKEY_X,
971 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
972 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
973 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
975 EXPECT_FALSE(GetController()->Process(shift_alt_press));
976 EXPECT_FALSE(GetController()->Process(shift_alt_x_press));
977 EXPECT_FALSE(GetController()->Process(shift_alt_x));
978 EXPECT_FALSE(GetController()->Process(shift_alt));
979 EXPECT_EQ(2, delegate->handle_next_ime_count());
981 // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
982 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
983 const ui::Accelerator shift_alt_return_press(
984 ui::VKEY_RETURN,
985 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
986 const ReleaseAccelerator shift_alt_return(
987 ui::VKEY_RETURN,
988 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
990 EXPECT_FALSE(GetController()->Process(shift_alt_press));
991 EXPECT_FALSE(GetController()->Process(shift_alt_return_press));
992 EXPECT_FALSE(GetController()->Process(shift_alt_return));
993 EXPECT_FALSE(GetController()->Process(shift_alt));
994 EXPECT_EQ(3, delegate->handle_next_ime_count());
996 const ui::Accelerator shift_alt_space_press(
997 ui::VKEY_SPACE,
998 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
999 const ReleaseAccelerator shift_alt_space(
1000 ui::VKEY_SPACE,
1001 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1003 EXPECT_FALSE(GetController()->Process(shift_alt_press));
1004 EXPECT_FALSE(GetController()->Process(shift_alt_space_press));
1005 EXPECT_FALSE(GetController()->Process(shift_alt_space));
1006 EXPECT_FALSE(GetController()->Process(shift_alt));
1007 EXPECT_EQ(4, delegate->handle_next_ime_count());
1010 #if defined(OS_CHROMEOS)
1011 // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
1013 const ui::Accelerator shift_alt_press(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1014 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1015 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1016 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1018 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
1019 GetController()->SetImeControlDelegate(
1020 scoped_ptr<ImeControlDelegate>(delegate).Pass());
1021 EXPECT_EQ(0, delegate->handle_next_ime_count());
1022 EXPECT_FALSE(GetController()->Process(shift_alt_press));
1023 EXPECT_FALSE(GetController()->Process(shift_alt));
1024 EXPECT_EQ(1, delegate->handle_next_ime_count());
1025 EXPECT_FALSE(GetController()->Process(alt_shift_press));
1026 EXPECT_FALSE(GetController()->Process(alt_shift));
1027 EXPECT_EQ(2, delegate->handle_next_ime_count());
1029 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1030 // released.
1031 const ui::Accelerator shift_alt_x_press(
1032 ui::VKEY_X,
1033 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1034 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
1035 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1037 EXPECT_FALSE(GetController()->Process(shift_alt_press));
1038 EXPECT_FALSE(GetController()->Process(shift_alt_x_press));
1039 EXPECT_FALSE(GetController()->Process(shift_alt_x));
1040 EXPECT_FALSE(GetController()->Process(shift_alt));
1041 EXPECT_EQ(2, delegate->handle_next_ime_count());
1043 #endif
1046 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1047 TEST_F(AcceleratorControllerTest, ImeGlobalAcceleratorsWorkaround139556) {
1048 // The workaround for crbug.com/139556 depends on the fact that we don't
1049 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1050 const ui::Accelerator shift_alt_return_press(
1051 ui::VKEY_RETURN,
1052 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1053 EXPECT_FALSE(GetController()->Process(shift_alt_return_press));
1054 const ui::Accelerator shift_alt_space_press(
1055 ui::VKEY_SPACE,
1056 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1057 EXPECT_FALSE(GetController()->Process(shift_alt_space_press));
1060 TEST_F(AcceleratorControllerTest, ReservedAccelerators) {
1061 // (Shift+)Alt+Tab and Chrome OS top-row keys are reserved.
1062 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1063 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
1064 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1065 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
1066 #if defined(OS_CHROMEOS)
1067 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1068 ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE)));
1069 #endif
1070 // Others are not reserved.
1071 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1072 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1073 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1074 ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE)));
1075 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1076 ui::Accelerator(ui::VKEY_A, ui::EF_NONE)));
1079 #if defined(OS_CHROMEOS)
1080 TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) {
1081 std::set<AcceleratorAction> all_actions;
1082 for (size_t i = 0 ; i < kAcceleratorDataLength; ++i)
1083 all_actions.insert(kAcceleratorData[i].action);
1084 #if !defined(NDEBUG)
1085 std::set<AcceleratorAction> all_desktop_actions;
1086 for (size_t i = 0 ; i < kDesktopAcceleratorDataLength; ++i)
1087 all_desktop_actions.insert(kDesktopAcceleratorData[i].action);
1088 #endif
1090 std::set<AcceleratorAction> actionsAllowedAtModalWindow;
1091 for (size_t k = 0 ; k < kActionsAllowedAtModalWindowLength; ++k)
1092 actionsAllowedAtModalWindow.insert(kActionsAllowedAtModalWindow[k]);
1093 for (std::set<AcceleratorAction>::const_iterator it =
1094 actionsAllowedAtModalWindow.begin();
1095 it != actionsAllowedAtModalWindow.end(); ++it) {
1096 EXPECT_TRUE(all_actions.find(*it) != all_actions.end()
1098 #if !defined(NDEBUG)
1099 || all_desktop_actions.find(*it) != all_desktop_actions.end()
1100 #endif
1102 << " action from kActionsAllowedAtModalWindow"
1103 << " not found in kAcceleratorData or kDesktopAcceleratorData. "
1104 << "action: " << *it;
1106 scoped_ptr<aura::Window> window(
1107 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1108 const ui::Accelerator dummy;
1109 wm::ActivateWindow(window.get());
1110 Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1111 for (std::set<AcceleratorAction>::const_iterator it = all_actions.begin();
1112 it != all_actions.end(); ++it) {
1113 if (actionsAllowedAtModalWindow.find(*it) ==
1114 actionsAllowedAtModalWindow.end()) {
1115 EXPECT_TRUE(GetController()->PerformAction(*it, dummy))
1116 << " for action (disallowed at modal window): " << *it;
1119 // Testing of top row (F5-F10) accelerators that should still work
1120 // when a modal window is open
1122 // Screenshot
1124 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
1125 delegate->set_can_take_screenshot(false);
1126 EXPECT_TRUE(GetController()->Process(
1127 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1128 EXPECT_TRUE(
1129 GetController()->Process(ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1130 EXPECT_TRUE(GetController()->Process(ui::Accelerator(
1131 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1132 delegate->set_can_take_screenshot(true);
1133 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
1134 EXPECT_TRUE(GetController()->Process(
1135 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1136 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
1137 EXPECT_TRUE(
1138 GetController()->Process(ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1139 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1140 EXPECT_TRUE(GetController()->Process(ui::Accelerator(
1141 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1142 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1144 // Brightness
1145 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
1146 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
1148 DummyBrightnessControlDelegate* delegate =
1149 new DummyBrightnessControlDelegate(false);
1150 GetController()->SetBrightnessControlDelegate(
1151 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1152 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1153 EXPECT_FALSE(GetController()->Process(brightness_down));
1154 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1155 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1156 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1157 EXPECT_FALSE(GetController()->Process(brightness_up));
1158 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1159 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1162 DummyBrightnessControlDelegate* delegate =
1163 new DummyBrightnessControlDelegate(true);
1164 GetController()->SetBrightnessControlDelegate(
1165 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1166 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1167 EXPECT_TRUE(GetController()->Process(brightness_down));
1168 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1169 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1170 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1171 EXPECT_TRUE(GetController()->Process(brightness_up));
1172 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1173 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1175 // Volume
1176 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
1177 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
1178 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
1180 EXPECT_TRUE(GetController()->Process(volume_mute));
1181 EXPECT_TRUE(GetController()->Process(volume_down));
1182 EXPECT_TRUE(GetController()->Process(volume_up));
1183 TestVolumeControlDelegate* delegate =
1184 new TestVolumeControlDelegate(false);
1185 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1186 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1187 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1188 EXPECT_FALSE(GetController()->Process(volume_mute));
1189 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1190 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1191 EXPECT_EQ(0, delegate->handle_volume_down_count());
1192 EXPECT_FALSE(GetController()->Process(volume_down));
1193 EXPECT_EQ(1, delegate->handle_volume_down_count());
1194 EXPECT_EQ(volume_down, delegate->last_accelerator());
1195 EXPECT_EQ(0, delegate->handle_volume_up_count());
1196 EXPECT_FALSE(GetController()->Process(volume_up));
1197 EXPECT_EQ(1, delegate->handle_volume_up_count());
1198 EXPECT_EQ(volume_up, delegate->last_accelerator());
1201 TestVolumeControlDelegate* delegate = new TestVolumeControlDelegate(true);
1202 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1203 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1204 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1205 EXPECT_TRUE(GetController()->Process(volume_mute));
1206 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1207 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1208 EXPECT_EQ(0, delegate->handle_volume_down_count());
1209 EXPECT_TRUE(GetController()->Process(volume_down));
1210 EXPECT_EQ(1, delegate->handle_volume_down_count());
1211 EXPECT_EQ(volume_down, delegate->last_accelerator());
1212 EXPECT_EQ(0, delegate->handle_volume_up_count());
1213 EXPECT_TRUE(GetController()->Process(volume_up));
1214 EXPECT_EQ(1, delegate->handle_volume_up_count());
1215 EXPECT_EQ(volume_up, delegate->last_accelerator());
1218 #endif
1220 TEST_F(AcceleratorControllerTest, DisallowedWithNoWindow) {
1221 const ui::Accelerator dummy;
1222 AccessibilityDelegate* delegate =
1223 ash::Shell::GetInstance()->accessibility_delegate();
1225 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1226 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1227 EXPECT_TRUE(
1228 GetController()->PerformAction(kActionsNeedingWindow[i], dummy));
1229 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED);
1232 // Make sure we don't alert if we do have a window.
1233 scoped_ptr<aura::Window> window;
1234 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1235 window.reset(CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1236 wm::ActivateWindow(window.get());
1237 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1238 GetController()->PerformAction(kActionsNeedingWindow[i], dummy);
1239 EXPECT_NE(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED);
1242 // Don't alert if we have a minimized window either.
1243 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1244 window.reset(CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1245 wm::ActivateWindow(window.get());
1246 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
1247 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1248 GetController()->PerformAction(kActionsNeedingWindow[i], dummy);
1249 EXPECT_NE(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED);
1253 } // namespace ash