Revert of Add nacl_loader_unittests to the chromium_builder_tests (https://codereview...
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller_unittest.cc
blob93277eafc08add99af78300ed01b1180649b3470
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"
6 #include "ash/accelerators/accelerator_table.h"
7 #include "ash/accessibility_delegate.h"
8 #include "ash/ash_switches.h"
9 #include "ash/display/display_manager.h"
10 #include "ash/ime_control_delegate.h"
11 #include "ash/screen_util.h"
12 #include "ash/shell.h"
13 #include "ash/shell_window_ids.h"
14 #include "ash/system/brightness_control_delegate.h"
15 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
16 #include "ash/system/tray/system_tray_delegate.h"
17 #include "ash/test/ash_test_base.h"
18 #include "ash/test/display_manager_test_api.h"
19 #include "ash/test/test_screenshot_delegate.h"
20 #include "ash/test/test_shell_delegate.h"
21 #include "ash/volume_control_delegate.h"
22 #include "ash/wm/window_state.h"
23 #include "ash/wm/window_util.h"
24 #include "base/command_line.h"
25 #include "ui/aura/test/test_window_delegate.h"
26 #include "ui/aura/test/test_windows.h"
27 #include "ui/aura/window.h"
28 #include "ui/events/event.h"
29 #include "ui/events/event_processor.h"
30 #include "ui/gfx/screen.h"
32 #if defined(USE_X11)
33 #include <X11/Xlib.h>
34 #include "ui/events/test/events_test_utils_x11.h"
35 #endif
37 namespace ash {
39 namespace {
41 class TestTarget : public ui::AcceleratorTarget {
42 public:
43 TestTarget() : accelerator_pressed_count_(0) {}
44 virtual ~TestTarget() {}
46 int accelerator_pressed_count() const {
47 return accelerator_pressed_count_;
50 void set_accelerator_pressed_count(int accelerator_pressed_count) {
51 accelerator_pressed_count_ = accelerator_pressed_count;
54 // Overridden from ui::AcceleratorTarget:
55 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
56 virtual bool CanHandleAccelerators() const OVERRIDE;
58 private:
59 int accelerator_pressed_count_;
61 DISALLOW_COPY_AND_ASSIGN(TestTarget);
64 class ReleaseAccelerator : public ui::Accelerator {
65 public:
66 ReleaseAccelerator(ui::KeyboardCode keycode, int modifiers)
67 : ui::Accelerator(keycode, modifiers) {
68 set_type(ui::ET_KEY_RELEASED);
72 class DummyVolumeControlDelegate : public VolumeControlDelegate {
73 public:
74 explicit DummyVolumeControlDelegate(bool consume)
75 : consume_(consume),
76 handle_volume_mute_count_(0),
77 handle_volume_down_count_(0),
78 handle_volume_up_count_(0) {
80 virtual ~DummyVolumeControlDelegate() {}
82 virtual bool HandleVolumeMute(const ui::Accelerator& accelerator) OVERRIDE {
83 ++handle_volume_mute_count_;
84 last_accelerator_ = accelerator;
85 return consume_;
87 virtual bool HandleVolumeDown(const ui::Accelerator& accelerator) OVERRIDE {
88 ++handle_volume_down_count_;
89 last_accelerator_ = accelerator;
90 return consume_;
92 virtual bool HandleVolumeUp(const ui::Accelerator& accelerator) OVERRIDE {
93 ++handle_volume_up_count_;
94 last_accelerator_ = accelerator;
95 return consume_;
98 int handle_volume_mute_count() const {
99 return handle_volume_mute_count_;
101 int handle_volume_down_count() const {
102 return handle_volume_down_count_;
104 int handle_volume_up_count() const {
105 return handle_volume_up_count_;
107 const ui::Accelerator& last_accelerator() const {
108 return last_accelerator_;
111 private:
112 const bool consume_;
113 int handle_volume_mute_count_;
114 int handle_volume_down_count_;
115 int handle_volume_up_count_;
116 ui::Accelerator last_accelerator_;
118 DISALLOW_COPY_AND_ASSIGN(DummyVolumeControlDelegate);
121 class DummyBrightnessControlDelegate : public BrightnessControlDelegate {
122 public:
123 explicit DummyBrightnessControlDelegate(bool consume)
124 : consume_(consume),
125 handle_brightness_down_count_(0),
126 handle_brightness_up_count_(0) {
128 virtual ~DummyBrightnessControlDelegate() {}
130 virtual bool HandleBrightnessDown(
131 const ui::Accelerator& accelerator) OVERRIDE {
132 ++handle_brightness_down_count_;
133 last_accelerator_ = accelerator;
134 return consume_;
136 virtual bool HandleBrightnessUp(const ui::Accelerator& accelerator) OVERRIDE {
137 ++handle_brightness_up_count_;
138 last_accelerator_ = accelerator;
139 return consume_;
141 virtual void SetBrightnessPercent(double percent, bool gradual) OVERRIDE {}
142 virtual void GetBrightnessPercent(
143 const base::Callback<void(double)>& callback) OVERRIDE {
144 callback.Run(100.0);
147 int handle_brightness_down_count() const {
148 return handle_brightness_down_count_;
150 int handle_brightness_up_count() const {
151 return handle_brightness_up_count_;
153 const ui::Accelerator& last_accelerator() const {
154 return last_accelerator_;
157 private:
158 const bool consume_;
159 int handle_brightness_down_count_;
160 int handle_brightness_up_count_;
161 ui::Accelerator last_accelerator_;
163 DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate);
166 class DummyImeControlDelegate : public ImeControlDelegate {
167 public:
168 explicit DummyImeControlDelegate(bool consume)
169 : consume_(consume),
170 handle_next_ime_count_(0),
171 handle_previous_ime_count_(0),
172 handle_switch_ime_count_(0) {
174 virtual ~DummyImeControlDelegate() {}
176 virtual bool HandleNextIme() OVERRIDE {
177 ++handle_next_ime_count_;
178 return consume_;
180 virtual bool HandlePreviousIme(const ui::Accelerator& accelerator) OVERRIDE {
181 ++handle_previous_ime_count_;
182 last_accelerator_ = accelerator;
183 return consume_;
185 virtual bool HandleSwitchIme(const ui::Accelerator& accelerator) OVERRIDE {
186 ++handle_switch_ime_count_;
187 last_accelerator_ = accelerator;
188 return consume_;
191 int handle_next_ime_count() const {
192 return handle_next_ime_count_;
194 int handle_previous_ime_count() const {
195 return handle_previous_ime_count_;
197 int handle_switch_ime_count() const {
198 return handle_switch_ime_count_;
200 const ui::Accelerator& last_accelerator() const {
201 return last_accelerator_;
203 virtual ui::Accelerator RemapAccelerator(
204 const ui::Accelerator& accelerator) OVERRIDE {
205 return ui::Accelerator(accelerator);
208 private:
209 const bool consume_;
210 int handle_next_ime_count_;
211 int handle_previous_ime_count_;
212 int handle_switch_ime_count_;
213 ui::Accelerator last_accelerator_;
215 DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate);
218 class DummyKeyboardBrightnessControlDelegate
219 : public KeyboardBrightnessControlDelegate {
220 public:
221 explicit DummyKeyboardBrightnessControlDelegate(bool consume)
222 : consume_(consume),
223 handle_keyboard_brightness_down_count_(0),
224 handle_keyboard_brightness_up_count_(0) {
226 virtual ~DummyKeyboardBrightnessControlDelegate() {}
228 virtual bool HandleKeyboardBrightnessDown(
229 const ui::Accelerator& accelerator) OVERRIDE {
230 ++handle_keyboard_brightness_down_count_;
231 last_accelerator_ = accelerator;
232 return consume_;
235 virtual bool HandleKeyboardBrightnessUp(
236 const ui::Accelerator& accelerator) OVERRIDE {
237 ++handle_keyboard_brightness_up_count_;
238 last_accelerator_ = accelerator;
239 return consume_;
242 int handle_keyboard_brightness_down_count() const {
243 return handle_keyboard_brightness_down_count_;
246 int handle_keyboard_brightness_up_count() const {
247 return handle_keyboard_brightness_up_count_;
250 const ui::Accelerator& last_accelerator() const {
251 return last_accelerator_;
254 private:
255 const bool consume_;
256 int handle_keyboard_brightness_down_count_;
257 int handle_keyboard_brightness_up_count_;
258 ui::Accelerator last_accelerator_;
260 DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate);
263 bool TestTarget::AcceleratorPressed(const ui::Accelerator& accelerator) {
264 ++accelerator_pressed_count_;
265 return true;
268 bool TestTarget::CanHandleAccelerators() const {
269 return true;
272 } // namespace
274 class AcceleratorControllerTest : public test::AshTestBase {
275 public:
276 AcceleratorControllerTest() {}
277 virtual ~AcceleratorControllerTest() {}
279 protected:
280 void EnableInternalDisplay() {
281 test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
282 SetFirstDisplayAsInternalDisplay();
285 static AcceleratorController* GetController();
286 static bool ProcessWithContext(const ui::Accelerator& accelerator);
288 // Several functions to access ExitWarningHandler (as friend).
289 static void StubForTest(ExitWarningHandler* ewh) {
290 ewh->stub_timer_for_test_ = true;
292 static void Reset(ExitWarningHandler* ewh) {
293 ewh->state_ = ExitWarningHandler::IDLE;
295 static void SimulateTimerExpired(ExitWarningHandler* ewh) {
296 ewh->TimerAction();
298 static bool is_ui_shown(ExitWarningHandler* ewh) {
299 return !!ewh->widget_;
301 static bool is_idle(ExitWarningHandler* ewh) {
302 return ewh->state_ == ExitWarningHandler::IDLE;
304 static bool is_exiting(ExitWarningHandler* ewh) {
305 return ewh->state_ == ExitWarningHandler::EXITING;
308 private:
309 DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest);
312 AcceleratorController* AcceleratorControllerTest::GetController() {
313 return Shell::GetInstance()->accelerator_controller();
316 bool AcceleratorControllerTest::ProcessWithContext(
317 const ui::Accelerator& accelerator) {
318 AcceleratorController* controller = GetController();
319 controller->context()->UpdateContext(accelerator);
320 return controller->Process(accelerator);
323 #if !defined(OS_WIN)
324 // Double press of exit shortcut => exiting
325 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) {
326 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
327 ui::Accelerator release(press);
328 release.set_type(ui::ET_KEY_RELEASED);
329 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
330 ASSERT_TRUE(!!ewh);
331 StubForTest(ewh);
332 EXPECT_TRUE(is_idle(ewh));
333 EXPECT_FALSE(is_ui_shown(ewh));
334 EXPECT_TRUE(ProcessWithContext(press));
335 EXPECT_FALSE(ProcessWithContext(release));
336 EXPECT_FALSE(is_idle(ewh));
337 EXPECT_TRUE(is_ui_shown(ewh));
338 EXPECT_TRUE(ProcessWithContext(press)); // second press before timer.
339 EXPECT_FALSE(ProcessWithContext(release));
340 SimulateTimerExpired(ewh);
341 EXPECT_TRUE(is_exiting(ewh));
342 EXPECT_FALSE(is_ui_shown(ewh));
343 Reset(ewh);
346 // Single press of exit shortcut before timer => idle
347 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) {
348 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
349 ui::Accelerator release(press);
350 release.set_type(ui::ET_KEY_RELEASED);
351 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
352 ASSERT_TRUE(!!ewh);
353 StubForTest(ewh);
354 EXPECT_TRUE(is_idle(ewh));
355 EXPECT_FALSE(is_ui_shown(ewh));
356 EXPECT_TRUE(ProcessWithContext(press));
357 EXPECT_FALSE(ProcessWithContext(release));
358 EXPECT_FALSE(is_idle(ewh));
359 EXPECT_TRUE(is_ui_shown(ewh));
360 SimulateTimerExpired(ewh);
361 EXPECT_TRUE(is_idle(ewh));
362 EXPECT_FALSE(is_ui_shown(ewh));
363 Reset(ewh);
366 // Shutdown ash with exit warning bubble open should not crash.
367 TEST_F(AcceleratorControllerTest, LingeringExitWarningBubble) {
368 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
369 ASSERT_TRUE(!!ewh);
370 StubForTest(ewh);
372 // Trigger once to show the bubble.
373 ewh->HandleAccelerator();
374 EXPECT_FALSE(is_idle(ewh));
375 EXPECT_TRUE(is_ui_shown(ewh));
377 // Exit ash and there should be no crash
379 #endif // !defined(OS_WIN)
381 TEST_F(AcceleratorControllerTest, Register) {
382 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
383 TestTarget target;
384 GetController()->Register(accelerator_a, &target);
386 // The registered accelerator is processed.
387 EXPECT_TRUE(ProcessWithContext(accelerator_a));
388 EXPECT_EQ(1, target.accelerator_pressed_count());
391 TEST_F(AcceleratorControllerTest, RegisterMultipleTarget) {
392 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
393 TestTarget target1;
394 GetController()->Register(accelerator_a, &target1);
395 TestTarget target2;
396 GetController()->Register(accelerator_a, &target2);
398 // If multiple targets are registered with the same accelerator, the target
399 // registered later processes the accelerator.
400 EXPECT_TRUE(ProcessWithContext(accelerator_a));
401 EXPECT_EQ(0, target1.accelerator_pressed_count());
402 EXPECT_EQ(1, target2.accelerator_pressed_count());
405 TEST_F(AcceleratorControllerTest, Unregister) {
406 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
407 TestTarget target;
408 GetController()->Register(accelerator_a, &target);
409 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
410 GetController()->Register(accelerator_b, &target);
412 // Unregistering a different accelerator does not affect the other
413 // accelerator.
414 GetController()->Unregister(accelerator_b, &target);
415 EXPECT_TRUE(ProcessWithContext(accelerator_a));
416 EXPECT_EQ(1, target.accelerator_pressed_count());
418 // The unregistered accelerator is no longer processed.
419 target.set_accelerator_pressed_count(0);
420 GetController()->Unregister(accelerator_a, &target);
421 EXPECT_FALSE(ProcessWithContext(accelerator_a));
422 EXPECT_EQ(0, target.accelerator_pressed_count());
425 TEST_F(AcceleratorControllerTest, UnregisterAll) {
426 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
427 TestTarget target1;
428 GetController()->Register(accelerator_a, &target1);
429 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
430 GetController()->Register(accelerator_b, &target1);
431 const ui::Accelerator accelerator_c(ui::VKEY_C, ui::EF_NONE);
432 TestTarget target2;
433 GetController()->Register(accelerator_c, &target2);
434 GetController()->UnregisterAll(&target1);
436 // All the accelerators registered for |target1| are no longer processed.
437 EXPECT_FALSE(ProcessWithContext(accelerator_a));
438 EXPECT_FALSE(ProcessWithContext(accelerator_b));
439 EXPECT_EQ(0, target1.accelerator_pressed_count());
441 // UnregisterAll with a different target does not affect the other target.
442 EXPECT_TRUE(ProcessWithContext(accelerator_c));
443 EXPECT_EQ(1, target2.accelerator_pressed_count());
446 TEST_F(AcceleratorControllerTest, Process) {
447 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
448 TestTarget target1;
449 GetController()->Register(accelerator_a, &target1);
451 // The registered accelerator is processed.
452 EXPECT_TRUE(ProcessWithContext(accelerator_a));
453 EXPECT_EQ(1, target1.accelerator_pressed_count());
455 // The non-registered accelerator is not processed.
456 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
457 EXPECT_FALSE(ProcessWithContext(accelerator_b));
460 TEST_F(AcceleratorControllerTest, IsRegistered) {
461 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
462 const ui::Accelerator accelerator_shift_a(ui::VKEY_A, ui::EF_SHIFT_DOWN);
463 TestTarget target;
464 GetController()->Register(accelerator_a, &target);
465 EXPECT_TRUE(GetController()->IsRegistered(accelerator_a));
466 EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a));
467 GetController()->UnregisterAll(&target);
468 EXPECT_FALSE(GetController()->IsRegistered(accelerator_a));
471 TEST_F(AcceleratorControllerTest, WindowSnap) {
472 scoped_ptr<aura::Window> window(
473 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
474 const ui::Accelerator dummy;
476 wm::WindowState* window_state = wm::GetWindowState(window.get());
478 window_state->Activate();
481 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
482 gfx::Rect expected_bounds = wm::GetDefaultLeftSnappedWindowBoundsInParent(
483 window.get());
484 EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString());
487 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
488 gfx::Rect expected_bounds = wm::GetDefaultRightSnappedWindowBoundsInParent(
489 window.get());
490 EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString());
493 gfx::Rect normal_bounds = window_state->GetRestoreBoundsInParent();
495 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
496 EXPECT_TRUE(window_state->IsMaximized());
497 EXPECT_NE(normal_bounds.ToString(), window->bounds().ToString());
499 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
500 EXPECT_FALSE(window_state->IsMaximized());
501 // Window gets restored to its restore bounds since side-maximized state
502 // is treated as a "maximized" state.
503 EXPECT_EQ(normal_bounds.ToString(), window->bounds().ToString());
505 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
506 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
507 EXPECT_FALSE(window_state->IsMaximized());
509 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
510 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
511 EXPECT_FALSE(window_state->IsMaximized());
513 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
514 EXPECT_TRUE(window_state->IsMaximized());
515 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
516 EXPECT_FALSE(window_state->IsMaximized());
517 EXPECT_TRUE(window_state->IsMinimized());
518 window_state->Restore();
519 window_state->Activate();
522 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
523 EXPECT_TRUE(window_state->IsMinimized());
527 TEST_F(AcceleratorControllerTest, CenterWindowAccelerator) {
528 scoped_ptr<aura::Window> window(
529 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
530 const ui::Accelerator dummy;
531 wm::WindowState* window_state = wm::GetWindowState(window.get());
532 window_state->Activate();
534 // Center the window using accelerator.
535 GetController()->PerformAction(WINDOW_POSITION_CENTER, dummy);
536 gfx::Rect work_area =
537 Shell::GetScreen()->GetDisplayNearestWindow(window.get()).work_area();
538 gfx::Rect bounds = window->GetBoundsInScreen();
539 EXPECT_NEAR(bounds.x() - work_area.x(),
540 work_area.right() - bounds.right(),
542 EXPECT_NEAR(bounds.y() - work_area.y(),
543 work_area.bottom() - bounds.bottom(),
546 // Add the window to docked container and try to center it.
547 window->SetBounds(gfx::Rect(0, 0, 20, 20));
548 aura::Window* docked_container = Shell::GetContainer(
549 window->GetRootWindow(), kShellWindowId_DockedContainer);
550 docked_container->AddChild(window.get());
551 gfx::Rect docked_bounds = window->GetBoundsInScreen();
552 GetController()->PerformAction(WINDOW_POSITION_CENTER, dummy);
553 // It should not get centered and should remain docked.
554 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
555 EXPECT_EQ(docked_bounds.ToString(), window->GetBoundsInScreen().ToString());
558 TEST_F(AcceleratorControllerTest, ControllerContext) {
559 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
560 ui::Accelerator accelerator_a2(ui::VKEY_A, ui::EF_NONE);
561 ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
563 accelerator_a.set_type(ui::ET_KEY_PRESSED);
564 accelerator_a2.set_type(ui::ET_KEY_RELEASED);
565 accelerator_b.set_type(ui::ET_KEY_PRESSED);
567 EXPECT_FALSE(GetController()->context()->repeated());
568 EXPECT_EQ(ui::ET_UNKNOWN,
569 GetController()->context()->previous_accelerator().type());
571 GetController()->context()->UpdateContext(accelerator_a);
572 EXPECT_FALSE(GetController()->context()->repeated());
573 EXPECT_EQ(ui::ET_UNKNOWN,
574 GetController()->context()->previous_accelerator().type());
576 GetController()->context()->UpdateContext(accelerator_a2);
577 EXPECT_FALSE(GetController()->context()->repeated());
578 EXPECT_EQ(ui::ET_KEY_PRESSED,
579 GetController()->context()->previous_accelerator().type());
581 GetController()->context()->UpdateContext(accelerator_a2);
582 EXPECT_TRUE(GetController()->context()->repeated());
583 EXPECT_EQ(ui::ET_KEY_RELEASED,
584 GetController()->context()->previous_accelerator().type());
586 GetController()->context()->UpdateContext(accelerator_b);
587 EXPECT_FALSE(GetController()->context()->repeated());
588 EXPECT_EQ(ui::ET_KEY_RELEASED,
589 GetController()->context()->previous_accelerator().type());
592 #if defined(OS_WIN) && defined(USE_AURA)
593 // crbug.com/314674
594 #define MAYBE_SuppressToggleMaximized DISABLED_SuppressToggleMaximized
595 #else
596 #define MAYBE_SuppressToggleMaximized SuppressToggleMaximized
597 #endif
599 TEST_F(AcceleratorControllerTest, MAYBE_SuppressToggleMaximized) {
600 scoped_ptr<aura::Window> window(
601 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
602 wm::ActivateWindow(window.get());
603 const ui::Accelerator accelerator(ui::VKEY_A, ui::EF_NONE);
604 const ui::Accelerator empty_accelerator;
606 wm::WindowState* window_state = wm::GetWindowState(window.get());
608 // Toggling not suppressed.
609 GetController()->context()->UpdateContext(accelerator);
610 GetController()->PerformAction(TOGGLE_MAXIMIZED, accelerator);
611 EXPECT_TRUE(window_state->IsMaximized());
613 // The same accelerator - toggling suppressed.
614 GetController()->context()->UpdateContext(accelerator);
615 GetController()->PerformAction(TOGGLE_MAXIMIZED, accelerator);
616 EXPECT_TRUE(window_state->IsMaximized());
618 // Suppressed but not for gesture events.
619 GetController()->PerformAction(TOGGLE_MAXIMIZED, empty_accelerator);
620 EXPECT_FALSE(window_state->IsMaximized());
623 #if defined(OS_WIN) && defined(USE_AURA)
624 // crbug.com/317592
625 #define MAYBE_ProcessOnce DISABLED_ProcessOnce
626 #else
627 #define MAYBE_ProcessOnce ProcessOnce
628 #endif
630 #if defined(OS_WIN) || defined(USE_X11)
631 TEST_F(AcceleratorControllerTest, MAYBE_ProcessOnce) {
632 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
633 TestTarget target;
634 GetController()->Register(accelerator_a, &target);
636 // The accelerator is processed only once.
637 ui::EventProcessor* dispatcher =
638 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
639 #if defined(OS_WIN)
640 MSG msg1 = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 };
641 ui::TranslatedKeyEvent key_event1(msg1, false);
642 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1);
643 EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed);
645 MSG msg2 = { NULL, WM_CHAR, L'A', 0 };
646 ui::TranslatedKeyEvent key_event2(msg2, true);
647 details = dispatcher->OnEventFromSource(&key_event2);
648 EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed);
650 MSG msg3 = { NULL, WM_KEYUP, ui::VKEY_A, 0 };
651 ui::TranslatedKeyEvent key_event3(msg3, false);
652 details = dispatcher->OnEventFromSource(&key_event3);
653 EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed);
654 #elif defined(USE_X11)
655 ui::ScopedXI2Event key_event;
656 key_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
657 ui::TranslatedKeyEvent key_event1(key_event, false);
658 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1);
659 EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed);
661 ui::TranslatedKeyEvent key_event2(key_event, true);
662 details = dispatcher->OnEventFromSource(&key_event2);
663 EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed);
665 key_event.InitKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_A, 0);
666 ui::TranslatedKeyEvent key_event3(key_event, false);
667 details = dispatcher->OnEventFromSource(&key_event3);
668 EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed);
669 #endif
670 EXPECT_EQ(1, target.accelerator_pressed_count());
672 #endif
674 TEST_F(AcceleratorControllerTest, GlobalAccelerators) {
675 // CycleBackward
676 EXPECT_TRUE(ProcessWithContext(
677 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
678 // CycleForward
679 EXPECT_TRUE(ProcessWithContext(
680 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
681 // CycleLinear
682 EXPECT_TRUE(ProcessWithContext(
683 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE)));
685 #if defined(OS_CHROMEOS)
686 // Take screenshot / partial screenshot
687 // True should always be returned regardless of the existence of the delegate.
689 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
690 delegate->set_can_take_screenshot(false);
691 EXPECT_TRUE(ProcessWithContext(
692 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
693 EXPECT_TRUE(ProcessWithContext(
694 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
695 EXPECT_TRUE(ProcessWithContext(
696 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
697 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
699 delegate->set_can_take_screenshot(true);
700 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
701 EXPECT_TRUE(ProcessWithContext(
702 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
703 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
704 EXPECT_TRUE(ProcessWithContext(
705 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
706 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
707 EXPECT_TRUE(ProcessWithContext(
708 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
709 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
710 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
712 #endif
713 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
714 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
715 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
717 DummyVolumeControlDelegate* delegate =
718 new DummyVolumeControlDelegate(false);
719 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
720 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
721 EXPECT_EQ(0, delegate->handle_volume_mute_count());
722 EXPECT_FALSE(ProcessWithContext(volume_mute));
723 EXPECT_EQ(1, delegate->handle_volume_mute_count());
724 EXPECT_EQ(volume_mute, delegate->last_accelerator());
725 EXPECT_EQ(0, delegate->handle_volume_down_count());
726 EXPECT_FALSE(ProcessWithContext(volume_down));
727 EXPECT_EQ(1, delegate->handle_volume_down_count());
728 EXPECT_EQ(volume_down, delegate->last_accelerator());
729 EXPECT_EQ(0, delegate->handle_volume_up_count());
730 EXPECT_FALSE(ProcessWithContext(volume_up));
731 EXPECT_EQ(1, delegate->handle_volume_up_count());
732 EXPECT_EQ(volume_up, delegate->last_accelerator());
735 DummyVolumeControlDelegate* delegate = new DummyVolumeControlDelegate(true);
736 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
737 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
738 EXPECT_EQ(0, delegate->handle_volume_mute_count());
739 EXPECT_TRUE(ProcessWithContext(volume_mute));
740 EXPECT_EQ(1, delegate->handle_volume_mute_count());
741 EXPECT_EQ(volume_mute, delegate->last_accelerator());
742 EXPECT_EQ(0, delegate->handle_volume_down_count());
743 EXPECT_TRUE(ProcessWithContext(volume_down));
744 EXPECT_EQ(1, delegate->handle_volume_down_count());
745 EXPECT_EQ(volume_down, delegate->last_accelerator());
746 EXPECT_EQ(0, delegate->handle_volume_up_count());
747 EXPECT_TRUE(ProcessWithContext(volume_up));
748 EXPECT_EQ(1, delegate->handle_volume_up_count());
749 EXPECT_EQ(volume_up, delegate->last_accelerator());
751 #if defined(OS_CHROMEOS)
752 // Brightness
753 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
754 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
755 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
757 DummyBrightnessControlDelegate* delegate =
758 new DummyBrightnessControlDelegate(false);
759 GetController()->SetBrightnessControlDelegate(
760 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
761 EXPECT_EQ(0, delegate->handle_brightness_down_count());
762 EXPECT_FALSE(ProcessWithContext(brightness_down));
763 EXPECT_EQ(1, delegate->handle_brightness_down_count());
764 EXPECT_EQ(brightness_down, delegate->last_accelerator());
765 EXPECT_EQ(0, delegate->handle_brightness_up_count());
766 EXPECT_FALSE(ProcessWithContext(brightness_up));
767 EXPECT_EQ(1, delegate->handle_brightness_up_count());
768 EXPECT_EQ(brightness_up, delegate->last_accelerator());
771 DummyBrightnessControlDelegate* delegate =
772 new DummyBrightnessControlDelegate(true);
773 GetController()->SetBrightnessControlDelegate(
774 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
775 EXPECT_EQ(0, delegate->handle_brightness_down_count());
776 EXPECT_TRUE(ProcessWithContext(brightness_down));
777 EXPECT_EQ(1, delegate->handle_brightness_down_count());
778 EXPECT_EQ(brightness_down, delegate->last_accelerator());
779 EXPECT_EQ(0, delegate->handle_brightness_up_count());
780 EXPECT_TRUE(ProcessWithContext(brightness_up));
781 EXPECT_EQ(1, delegate->handle_brightness_up_count());
782 EXPECT_EQ(brightness_up, delegate->last_accelerator());
785 // Keyboard brightness
786 const ui::Accelerator alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN,
787 ui::EF_ALT_DOWN);
788 const ui::Accelerator alt_brightness_up(ui::VKEY_BRIGHTNESS_UP,
789 ui::EF_ALT_DOWN);
791 EXPECT_TRUE(ProcessWithContext(alt_brightness_down));
792 EXPECT_TRUE(ProcessWithContext(alt_brightness_up));
793 DummyKeyboardBrightnessControlDelegate* delegate =
794 new DummyKeyboardBrightnessControlDelegate(false);
795 GetController()->SetKeyboardBrightnessControlDelegate(
796 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
797 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
798 EXPECT_FALSE(ProcessWithContext(alt_brightness_down));
799 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
800 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
801 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
802 EXPECT_FALSE(ProcessWithContext(alt_brightness_up));
803 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
804 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
807 DummyKeyboardBrightnessControlDelegate* delegate =
808 new DummyKeyboardBrightnessControlDelegate(true);
809 GetController()->SetKeyboardBrightnessControlDelegate(
810 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
811 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
812 EXPECT_TRUE(ProcessWithContext(alt_brightness_down));
813 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
814 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
815 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
816 EXPECT_TRUE(ProcessWithContext(alt_brightness_up));
817 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
818 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
820 #endif
822 #if !defined(NDEBUG)
823 // ToggleDesktopBackgroundMode
824 EXPECT_TRUE(ProcessWithContext(
825 ui::Accelerator(ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)));
826 #if !defined(OS_LINUX)
827 // ToggleDesktopFullScreen (not implemented yet on Linux)
828 EXPECT_TRUE(ProcessWithContext(
829 ui::Accelerator(ui::VKEY_F11, ui::EF_CONTROL_DOWN)));
830 #endif // OS_LINUX
831 #endif // !NDEBUG
833 #if !defined(OS_WIN)
834 // Exit
835 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
836 ASSERT_TRUE(!!ewh);
837 StubForTest(ewh);
838 EXPECT_TRUE(is_idle(ewh));
839 EXPECT_FALSE(is_ui_shown(ewh));
840 EXPECT_TRUE(ProcessWithContext(
841 ui::Accelerator(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
842 EXPECT_FALSE(is_idle(ewh));
843 EXPECT_TRUE(is_ui_shown(ewh));
844 SimulateTimerExpired(ewh);
845 EXPECT_TRUE(is_idle(ewh));
846 EXPECT_FALSE(is_ui_shown(ewh));
847 Reset(ewh);
848 #endif
850 // New tab
851 EXPECT_TRUE(ProcessWithContext(
852 ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN)));
854 // New incognito window
855 EXPECT_TRUE(ProcessWithContext(
856 ui::Accelerator(ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
858 // New window
859 EXPECT_TRUE(ProcessWithContext(
860 ui::Accelerator(ui::VKEY_N, ui::EF_CONTROL_DOWN)));
862 // Restore tab
863 EXPECT_TRUE(ProcessWithContext(
864 ui::Accelerator(ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
866 // Show task manager
867 EXPECT_TRUE(ProcessWithContext(
868 ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN)));
870 #if defined(OS_CHROMEOS)
871 // Open file manager
872 EXPECT_TRUE(ProcessWithContext(
873 ui::Accelerator(ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
875 // Lock screen
876 // NOTE: Accelerators that do not work on the lock screen need to be
877 // tested before the sequence below is invoked because it causes a side
878 // effect of locking the screen.
879 EXPECT_TRUE(ProcessWithContext(
880 ui::Accelerator(ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
881 #endif
884 TEST_F(AcceleratorControllerTest, GlobalAcceleratorsToggleAppList) {
885 AccessibilityDelegate* delegate =
886 ash::Shell::GetInstance()->accessibility_delegate();
887 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
889 // The press event should not open the AppList, the release should instead.
890 EXPECT_FALSE(ProcessWithContext(
891 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
892 EXPECT_TRUE(ProcessWithContext(
893 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
894 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
896 // When spoken feedback is on, the AppList should not toggle.
897 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
898 EXPECT_FALSE(ProcessWithContext(
899 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
900 EXPECT_FALSE(ProcessWithContext(
901 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
902 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
903 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
905 EXPECT_FALSE(ProcessWithContext(
906 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
907 EXPECT_TRUE(ProcessWithContext(
908 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
909 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
911 // When spoken feedback is on, the AppList should not toggle.
912 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
913 EXPECT_FALSE(ProcessWithContext(
914 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
915 EXPECT_FALSE(ProcessWithContext(
916 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
917 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
918 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
921 TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) {
922 // Test IME shortcuts.
924 const ui::Accelerator control_space(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
925 const ui::Accelerator convert(ui::VKEY_CONVERT, ui::EF_NONE);
926 const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, ui::EF_NONE);
927 const ui::Accelerator wide_half_1(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE);
928 const ui::Accelerator wide_half_2(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE);
929 const ui::Accelerator hangul(ui::VKEY_HANGUL, ui::EF_NONE);
930 EXPECT_FALSE(ProcessWithContext(control_space));
931 EXPECT_FALSE(ProcessWithContext(convert));
932 EXPECT_FALSE(ProcessWithContext(non_convert));
933 EXPECT_FALSE(ProcessWithContext(wide_half_1));
934 EXPECT_FALSE(ProcessWithContext(wide_half_2));
935 EXPECT_FALSE(ProcessWithContext(hangul));
936 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
937 GetController()->SetImeControlDelegate(
938 scoped_ptr<ImeControlDelegate>(delegate).Pass());
939 EXPECT_EQ(0, delegate->handle_previous_ime_count());
940 EXPECT_TRUE(ProcessWithContext(control_space));
941 EXPECT_EQ(1, delegate->handle_previous_ime_count());
942 EXPECT_EQ(0, delegate->handle_switch_ime_count());
943 EXPECT_TRUE(ProcessWithContext(convert));
944 EXPECT_EQ(1, delegate->handle_switch_ime_count());
945 EXPECT_TRUE(ProcessWithContext(non_convert));
946 EXPECT_EQ(2, delegate->handle_switch_ime_count());
947 EXPECT_TRUE(ProcessWithContext(wide_half_1));
948 EXPECT_EQ(3, delegate->handle_switch_ime_count());
949 EXPECT_TRUE(ProcessWithContext(wide_half_2));
950 EXPECT_EQ(4, delegate->handle_switch_ime_count());
951 EXPECT_TRUE(ProcessWithContext(hangul));
952 EXPECT_EQ(5, delegate->handle_switch_ime_count());
955 // Test IME shortcuts that are triggered on key release.
957 const ui::Accelerator shift_alt_press(ui::VKEY_MENU,
958 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
959 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
960 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT,
961 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
962 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
964 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
965 GetController()->SetImeControlDelegate(
966 scoped_ptr<ImeControlDelegate>(delegate).Pass());
967 EXPECT_EQ(0, delegate->handle_next_ime_count());
968 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
969 EXPECT_TRUE(ProcessWithContext(shift_alt));
970 EXPECT_EQ(1, delegate->handle_next_ime_count());
971 EXPECT_FALSE(ProcessWithContext(alt_shift_press));
972 EXPECT_TRUE(ProcessWithContext(alt_shift));
973 EXPECT_EQ(2, delegate->handle_next_ime_count());
975 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
976 // released.
977 const ui::Accelerator shift_alt_x_press(
978 ui::VKEY_X,
979 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
980 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
981 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
983 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
984 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press));
985 EXPECT_FALSE(ProcessWithContext(shift_alt_x));
986 EXPECT_FALSE(ProcessWithContext(shift_alt));
987 EXPECT_EQ(2, delegate->handle_next_ime_count());
989 // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
990 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
991 const ui::Accelerator shift_alt_return_press(
992 ui::VKEY_RETURN,
993 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
994 const ReleaseAccelerator shift_alt_return(
995 ui::VKEY_RETURN,
996 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
998 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
999 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press));
1000 EXPECT_FALSE(ProcessWithContext(shift_alt_return));
1001 EXPECT_TRUE(ProcessWithContext(shift_alt));
1002 EXPECT_EQ(3, delegate->handle_next_ime_count());
1004 const ui::Accelerator shift_alt_space_press(
1005 ui::VKEY_SPACE,
1006 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1007 const ReleaseAccelerator shift_alt_space(
1008 ui::VKEY_SPACE,
1009 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1011 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1012 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press));
1013 EXPECT_FALSE(ProcessWithContext(shift_alt_space));
1014 EXPECT_TRUE(ProcessWithContext(shift_alt));
1015 EXPECT_EQ(4, delegate->handle_next_ime_count());
1018 #if defined(OS_CHROMEOS)
1019 // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
1021 const ui::Accelerator shift_alt_press(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1022 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1023 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1024 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1026 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
1027 GetController()->SetImeControlDelegate(
1028 scoped_ptr<ImeControlDelegate>(delegate).Pass());
1029 EXPECT_EQ(0, delegate->handle_next_ime_count());
1030 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1031 EXPECT_TRUE(ProcessWithContext(shift_alt));
1032 EXPECT_EQ(1, delegate->handle_next_ime_count());
1033 EXPECT_FALSE(ProcessWithContext(alt_shift_press));
1034 EXPECT_TRUE(ProcessWithContext(alt_shift));
1035 EXPECT_EQ(2, delegate->handle_next_ime_count());
1037 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1038 // released.
1039 const ui::Accelerator shift_alt_x_press(
1040 ui::VKEY_X,
1041 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1042 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
1043 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1045 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1046 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press));
1047 EXPECT_FALSE(ProcessWithContext(shift_alt_x));
1048 EXPECT_FALSE(ProcessWithContext(shift_alt));
1049 EXPECT_EQ(2, delegate->handle_next_ime_count());
1051 #endif
1054 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1055 TEST_F(AcceleratorControllerTest, ImeGlobalAcceleratorsWorkaround139556) {
1056 // The workaround for crbug.com/139556 depends on the fact that we don't
1057 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1058 const ui::Accelerator shift_alt_return_press(
1059 ui::VKEY_RETURN,
1060 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1061 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press));
1062 const ui::Accelerator shift_alt_space_press(
1063 ui::VKEY_SPACE,
1064 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1065 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press));
1068 TEST_F(AcceleratorControllerTest, ReservedAccelerators) {
1069 // (Shift+)Alt+Tab and Chrome OS top-row keys are reserved.
1070 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1071 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
1072 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1073 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
1074 #if defined(OS_CHROMEOS)
1075 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1076 ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE)));
1077 #endif
1078 // Others are not reserved.
1079 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1080 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1081 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1082 ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE)));
1083 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1084 ui::Accelerator(ui::VKEY_A, ui::EF_NONE)));
1087 #if defined(OS_CHROMEOS)
1088 TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) {
1089 std::set<AcceleratorAction> all_actions;
1090 for (size_t i = 0 ; i < kAcceleratorDataLength; ++i)
1091 all_actions.insert(kAcceleratorData[i].action);
1092 #if !defined(NDEBUG)
1093 std::set<AcceleratorAction> all_desktop_actions;
1094 for (size_t i = 0 ; i < kDesktopAcceleratorDataLength; ++i)
1095 all_desktop_actions.insert(kDesktopAcceleratorData[i].action);
1096 #endif
1098 std::set<AcceleratorAction> actionsAllowedAtModalWindow;
1099 for (size_t k = 0 ; k < kActionsAllowedAtModalWindowLength; ++k)
1100 actionsAllowedAtModalWindow.insert(kActionsAllowedAtModalWindow[k]);
1101 for (std::set<AcceleratorAction>::const_iterator it =
1102 actionsAllowedAtModalWindow.begin();
1103 it != actionsAllowedAtModalWindow.end(); ++it) {
1104 EXPECT_TRUE(all_actions.find(*it) != all_actions.end()
1106 #if !defined(NDEBUG)
1107 || all_desktop_actions.find(*it) != all_desktop_actions.end()
1108 #endif
1110 << " action from kActionsAllowedAtModalWindow"
1111 << " not found in kAcceleratorData or kDesktopAcceleratorData. "
1112 << "action: " << *it;
1114 scoped_ptr<aura::Window> window(
1115 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1116 const ui::Accelerator dummy;
1117 wm::ActivateWindow(window.get());
1118 Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1119 for (std::set<AcceleratorAction>::const_iterator it = all_actions.begin();
1120 it != all_actions.end(); ++it) {
1121 if (actionsAllowedAtModalWindow.find(*it) ==
1122 actionsAllowedAtModalWindow.end()) {
1123 EXPECT_TRUE(GetController()->PerformAction(*it, dummy))
1124 << " for action (disallowed at modal window): " << *it;
1127 // Testing of top row (F5-F10) accelerators that should still work
1128 // when a modal window is open
1130 // Screenshot
1132 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
1133 delegate->set_can_take_screenshot(false);
1134 EXPECT_TRUE(ProcessWithContext(
1135 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1136 EXPECT_TRUE(ProcessWithContext(
1137 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1138 EXPECT_TRUE(ProcessWithContext(
1139 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
1140 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1141 delegate->set_can_take_screenshot(true);
1142 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
1143 EXPECT_TRUE(ProcessWithContext(
1144 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1145 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
1146 EXPECT_TRUE(ProcessWithContext(
1147 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1148 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1149 EXPECT_TRUE(ProcessWithContext(
1150 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
1151 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1152 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1154 // Brightness
1155 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
1156 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
1158 DummyBrightnessControlDelegate* delegate =
1159 new DummyBrightnessControlDelegate(false);
1160 GetController()->SetBrightnessControlDelegate(
1161 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1162 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1163 EXPECT_FALSE(ProcessWithContext(brightness_down));
1164 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1165 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1166 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1167 EXPECT_FALSE(ProcessWithContext(brightness_up));
1168 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1169 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1172 DummyBrightnessControlDelegate* delegate =
1173 new DummyBrightnessControlDelegate(true);
1174 GetController()->SetBrightnessControlDelegate(
1175 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1176 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1177 EXPECT_TRUE(ProcessWithContext(brightness_down));
1178 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1179 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1180 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1181 EXPECT_TRUE(ProcessWithContext(brightness_up));
1182 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1183 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1185 // Volume
1186 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
1187 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
1188 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
1190 EXPECT_TRUE(ProcessWithContext(volume_mute));
1191 EXPECT_TRUE(ProcessWithContext(volume_down));
1192 EXPECT_TRUE(ProcessWithContext(volume_up));
1193 DummyVolumeControlDelegate* delegate =
1194 new DummyVolumeControlDelegate(false);
1195 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1196 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1197 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1198 EXPECT_FALSE(ProcessWithContext(volume_mute));
1199 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1200 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1201 EXPECT_EQ(0, delegate->handle_volume_down_count());
1202 EXPECT_FALSE(ProcessWithContext(volume_down));
1203 EXPECT_EQ(1, delegate->handle_volume_down_count());
1204 EXPECT_EQ(volume_down, delegate->last_accelerator());
1205 EXPECT_EQ(0, delegate->handle_volume_up_count());
1206 EXPECT_FALSE(ProcessWithContext(volume_up));
1207 EXPECT_EQ(1, delegate->handle_volume_up_count());
1208 EXPECT_EQ(volume_up, delegate->last_accelerator());
1211 DummyVolumeControlDelegate* delegate = new DummyVolumeControlDelegate(true);
1212 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1213 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1214 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1215 EXPECT_TRUE(ProcessWithContext(volume_mute));
1216 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1217 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1218 EXPECT_EQ(0, delegate->handle_volume_down_count());
1219 EXPECT_TRUE(ProcessWithContext(volume_down));
1220 EXPECT_EQ(1, delegate->handle_volume_down_count());
1221 EXPECT_EQ(volume_down, delegate->last_accelerator());
1222 EXPECT_EQ(0, delegate->handle_volume_up_count());
1223 EXPECT_TRUE(ProcessWithContext(volume_up));
1224 EXPECT_EQ(1, delegate->handle_volume_up_count());
1225 EXPECT_EQ(volume_up, delegate->last_accelerator());
1228 #endif
1230 TEST_F(AcceleratorControllerTest, DisallowedWithNoWindow) {
1231 const ui::Accelerator dummy;
1232 AccessibilityDelegate* delegate =
1233 ash::Shell::GetInstance()->accessibility_delegate();
1235 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1236 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1237 EXPECT_TRUE(
1238 GetController()->PerformAction(kActionsNeedingWindow[i], dummy));
1239 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED);
1242 // Make sure we don't alert if we do have a window.
1243 scoped_ptr<aura::Window> window(
1244 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1245 wm::ActivateWindow(window.get());
1246 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1247 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1248 GetController()->PerformAction(kActionsNeedingWindow[i], dummy);
1249 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_NONE);
1252 // Don't alert if we have a minimized window either.
1253 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
1254 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1255 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1256 GetController()->PerformAction(kActionsNeedingWindow[i], dummy);
1257 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_NONE);
1261 } // namespace ash