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/test/test_window_delegate.h"
28 #include "ui/aura/test/test_windows.h"
29 #include "ui/aura/window.h"
30 #include "ui/events/event.h"
31 #include "ui/events/event_processor.h"
32 #include "ui/gfx/screen.h"
36 #include "ui/events/test/events_test_utils_x11.h"
43 class TestTarget : public ui::AcceleratorTarget {
45 TestTarget() : accelerator_pressed_count_(0) {}
46 virtual ~TestTarget() {}
48 int accelerator_pressed_count() const {
49 return accelerator_pressed_count_;
52 void set_accelerator_pressed_count(int accelerator_pressed_count) {
53 accelerator_pressed_count_ = accelerator_pressed_count;
56 // Overridden from ui::AcceleratorTarget:
57 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
58 virtual bool CanHandleAccelerators() const OVERRIDE;
61 int accelerator_pressed_count_;
63 DISALLOW_COPY_AND_ASSIGN(TestTarget);
66 class ReleaseAccelerator : public ui::Accelerator {
68 ReleaseAccelerator(ui::KeyboardCode keycode, int modifiers)
69 : ui::Accelerator(keycode, modifiers) {
70 set_type(ui::ET_KEY_RELEASED);
74 class DummyBrightnessControlDelegate : public BrightnessControlDelegate {
76 explicit DummyBrightnessControlDelegate(bool consume)
78 handle_brightness_down_count_(0),
79 handle_brightness_up_count_(0) {
81 virtual ~DummyBrightnessControlDelegate() {}
83 virtual bool HandleBrightnessDown(
84 const ui::Accelerator& accelerator) OVERRIDE {
85 ++handle_brightness_down_count_;
86 last_accelerator_ = accelerator;
89 virtual bool HandleBrightnessUp(const ui::Accelerator& accelerator) OVERRIDE {
90 ++handle_brightness_up_count_;
91 last_accelerator_ = accelerator;
94 virtual void SetBrightnessPercent(double percent, bool gradual) OVERRIDE {}
95 virtual void GetBrightnessPercent(
96 const base::Callback<void(double)>& callback) OVERRIDE {
100 int handle_brightness_down_count() const {
101 return handle_brightness_down_count_;
103 int handle_brightness_up_count() const {
104 return handle_brightness_up_count_;
106 const ui::Accelerator& last_accelerator() const {
107 return last_accelerator_;
112 int handle_brightness_down_count_;
113 int handle_brightness_up_count_;
114 ui::Accelerator last_accelerator_;
116 DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate);
119 class DummyImeControlDelegate : public ImeControlDelegate {
121 explicit DummyImeControlDelegate(bool consume)
123 handle_next_ime_count_(0),
124 handle_previous_ime_count_(0),
125 handle_switch_ime_count_(0) {
127 virtual ~DummyImeControlDelegate() {}
129 virtual bool HandleNextIme() OVERRIDE {
130 ++handle_next_ime_count_;
133 virtual bool HandlePreviousIme(const ui::Accelerator& accelerator) OVERRIDE {
134 ++handle_previous_ime_count_;
135 last_accelerator_ = accelerator;
138 virtual bool HandleSwitchIme(const ui::Accelerator& accelerator) OVERRIDE {
139 ++handle_switch_ime_count_;
140 last_accelerator_ = accelerator;
144 int handle_next_ime_count() const {
145 return handle_next_ime_count_;
147 int handle_previous_ime_count() const {
148 return handle_previous_ime_count_;
150 int handle_switch_ime_count() const {
151 return handle_switch_ime_count_;
153 const ui::Accelerator& last_accelerator() const {
154 return last_accelerator_;
156 virtual ui::Accelerator RemapAccelerator(
157 const ui::Accelerator& accelerator) OVERRIDE {
158 return ui::Accelerator(accelerator);
163 int handle_next_ime_count_;
164 int handle_previous_ime_count_;
165 int handle_switch_ime_count_;
166 ui::Accelerator last_accelerator_;
168 DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate);
171 class DummyKeyboardBrightnessControlDelegate
172 : public KeyboardBrightnessControlDelegate {
174 explicit DummyKeyboardBrightnessControlDelegate(bool consume)
176 handle_keyboard_brightness_down_count_(0),
177 handle_keyboard_brightness_up_count_(0) {
179 virtual ~DummyKeyboardBrightnessControlDelegate() {}
181 virtual bool HandleKeyboardBrightnessDown(
182 const ui::Accelerator& accelerator) OVERRIDE {
183 ++handle_keyboard_brightness_down_count_;
184 last_accelerator_ = accelerator;
188 virtual bool HandleKeyboardBrightnessUp(
189 const ui::Accelerator& accelerator) OVERRIDE {
190 ++handle_keyboard_brightness_up_count_;
191 last_accelerator_ = accelerator;
195 int handle_keyboard_brightness_down_count() const {
196 return handle_keyboard_brightness_down_count_;
199 int handle_keyboard_brightness_up_count() const {
200 return handle_keyboard_brightness_up_count_;
203 const ui::Accelerator& last_accelerator() const {
204 return last_accelerator_;
209 int handle_keyboard_brightness_down_count_;
210 int handle_keyboard_brightness_up_count_;
211 ui::Accelerator last_accelerator_;
213 DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate);
216 bool TestTarget::AcceleratorPressed(const ui::Accelerator& accelerator) {
217 ++accelerator_pressed_count_;
221 bool TestTarget::CanHandleAccelerators() const {
227 class AcceleratorControllerTest : public test::AshTestBase {
229 AcceleratorControllerTest() {}
230 virtual ~AcceleratorControllerTest() {}
233 void EnableInternalDisplay() {
234 test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
235 SetFirstDisplayAsInternalDisplay();
238 static AcceleratorController* GetController();
239 static bool ProcessWithContext(const ui::Accelerator& accelerator);
241 // Several functions to access ExitWarningHandler (as friend).
242 static void StubForTest(ExitWarningHandler* ewh) {
243 ewh->stub_timer_for_test_ = true;
245 static void Reset(ExitWarningHandler* ewh) {
246 ewh->state_ = ExitWarningHandler::IDLE;
248 static void SimulateTimerExpired(ExitWarningHandler* ewh) {
251 static bool is_ui_shown(ExitWarningHandler* ewh) {
252 return !!ewh->widget_;
254 static bool is_idle(ExitWarningHandler* ewh) {
255 return ewh->state_ == ExitWarningHandler::IDLE;
257 static bool is_exiting(ExitWarningHandler* ewh) {
258 return ewh->state_ == ExitWarningHandler::EXITING;
262 DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest);
265 AcceleratorController* AcceleratorControllerTest::GetController() {
266 return Shell::GetInstance()->accelerator_controller();
269 bool AcceleratorControllerTest::ProcessWithContext(
270 const ui::Accelerator& accelerator) {
271 AcceleratorController* controller = GetController();
272 controller->context()->UpdateContext(accelerator);
273 return controller->Process(accelerator);
277 // Double press of exit shortcut => exiting
278 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) {
279 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
280 ui::Accelerator release(press);
281 release.set_type(ui::ET_KEY_RELEASED);
282 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
285 EXPECT_TRUE(is_idle(ewh));
286 EXPECT_FALSE(is_ui_shown(ewh));
287 EXPECT_TRUE(ProcessWithContext(press));
288 EXPECT_FALSE(ProcessWithContext(release));
289 EXPECT_FALSE(is_idle(ewh));
290 EXPECT_TRUE(is_ui_shown(ewh));
291 EXPECT_TRUE(ProcessWithContext(press)); // second press before timer.
292 EXPECT_FALSE(ProcessWithContext(release));
293 SimulateTimerExpired(ewh);
294 EXPECT_TRUE(is_exiting(ewh));
295 EXPECT_FALSE(is_ui_shown(ewh));
299 // Single press of exit shortcut before timer => idle
300 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) {
301 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
302 ui::Accelerator release(press);
303 release.set_type(ui::ET_KEY_RELEASED);
304 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
307 EXPECT_TRUE(is_idle(ewh));
308 EXPECT_FALSE(is_ui_shown(ewh));
309 EXPECT_TRUE(ProcessWithContext(press));
310 EXPECT_FALSE(ProcessWithContext(release));
311 EXPECT_FALSE(is_idle(ewh));
312 EXPECT_TRUE(is_ui_shown(ewh));
313 SimulateTimerExpired(ewh);
314 EXPECT_TRUE(is_idle(ewh));
315 EXPECT_FALSE(is_ui_shown(ewh));
319 // Shutdown ash with exit warning bubble open should not crash.
320 TEST_F(AcceleratorControllerTest, LingeringExitWarningBubble) {
321 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
325 // Trigger once to show the bubble.
326 ewh->HandleAccelerator();
327 EXPECT_FALSE(is_idle(ewh));
328 EXPECT_TRUE(is_ui_shown(ewh));
330 // Exit ash and there should be no crash
332 #endif // !defined(OS_WIN)
334 TEST_F(AcceleratorControllerTest, Register) {
335 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
337 GetController()->Register(accelerator_a, &target);
339 // The registered accelerator is processed.
340 EXPECT_TRUE(ProcessWithContext(accelerator_a));
341 EXPECT_EQ(1, target.accelerator_pressed_count());
344 TEST_F(AcceleratorControllerTest, RegisterMultipleTarget) {
345 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
347 GetController()->Register(accelerator_a, &target1);
349 GetController()->Register(accelerator_a, &target2);
351 // If multiple targets are registered with the same accelerator, the target
352 // registered later processes the accelerator.
353 EXPECT_TRUE(ProcessWithContext(accelerator_a));
354 EXPECT_EQ(0, target1.accelerator_pressed_count());
355 EXPECT_EQ(1, target2.accelerator_pressed_count());
358 TEST_F(AcceleratorControllerTest, Unregister) {
359 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
361 GetController()->Register(accelerator_a, &target);
362 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
363 GetController()->Register(accelerator_b, &target);
365 // Unregistering a different accelerator does not affect the other
367 GetController()->Unregister(accelerator_b, &target);
368 EXPECT_TRUE(ProcessWithContext(accelerator_a));
369 EXPECT_EQ(1, target.accelerator_pressed_count());
371 // The unregistered accelerator is no longer processed.
372 target.set_accelerator_pressed_count(0);
373 GetController()->Unregister(accelerator_a, &target);
374 EXPECT_FALSE(ProcessWithContext(accelerator_a));
375 EXPECT_EQ(0, target.accelerator_pressed_count());
378 TEST_F(AcceleratorControllerTest, UnregisterAll) {
379 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
381 GetController()->Register(accelerator_a, &target1);
382 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
383 GetController()->Register(accelerator_b, &target1);
384 const ui::Accelerator accelerator_c(ui::VKEY_C, ui::EF_NONE);
386 GetController()->Register(accelerator_c, &target2);
387 GetController()->UnregisterAll(&target1);
389 // All the accelerators registered for |target1| are no longer processed.
390 EXPECT_FALSE(ProcessWithContext(accelerator_a));
391 EXPECT_FALSE(ProcessWithContext(accelerator_b));
392 EXPECT_EQ(0, target1.accelerator_pressed_count());
394 // UnregisterAll with a different target does not affect the other target.
395 EXPECT_TRUE(ProcessWithContext(accelerator_c));
396 EXPECT_EQ(1, target2.accelerator_pressed_count());
399 TEST_F(AcceleratorControllerTest, Process) {
400 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
402 GetController()->Register(accelerator_a, &target1);
404 // The registered accelerator is processed.
405 EXPECT_TRUE(ProcessWithContext(accelerator_a));
406 EXPECT_EQ(1, target1.accelerator_pressed_count());
408 // The non-registered accelerator is not processed.
409 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
410 EXPECT_FALSE(ProcessWithContext(accelerator_b));
413 TEST_F(AcceleratorControllerTest, IsRegistered) {
414 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
415 const ui::Accelerator accelerator_shift_a(ui::VKEY_A, ui::EF_SHIFT_DOWN);
417 GetController()->Register(accelerator_a, &target);
418 EXPECT_TRUE(GetController()->IsRegistered(accelerator_a));
419 EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a));
420 GetController()->UnregisterAll(&target);
421 EXPECT_FALSE(GetController()->IsRegistered(accelerator_a));
424 TEST_F(AcceleratorControllerTest, WindowSnap) {
425 scoped_ptr<aura::Window> window(
426 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
427 const ui::Accelerator dummy;
429 wm::WindowState* window_state = wm::GetWindowState(window.get());
431 window_state->Activate();
434 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
435 gfx::Rect expected_bounds = wm::GetDefaultLeftSnappedWindowBoundsInParent(
437 EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString());
440 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
441 gfx::Rect expected_bounds = wm::GetDefaultRightSnappedWindowBoundsInParent(
443 EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString());
446 gfx::Rect normal_bounds = window_state->GetRestoreBoundsInParent();
448 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
449 EXPECT_TRUE(window_state->IsMaximized());
450 EXPECT_NE(normal_bounds.ToString(), window->bounds().ToString());
452 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
453 EXPECT_FALSE(window_state->IsMaximized());
454 // Window gets restored to its restore bounds since side-maximized state
455 // is treated as a "maximized" state.
456 EXPECT_EQ(normal_bounds.ToString(), window->bounds().ToString());
458 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
459 GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
460 EXPECT_FALSE(window_state->IsMaximized());
462 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
463 GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
464 EXPECT_FALSE(window_state->IsMaximized());
466 GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
467 EXPECT_TRUE(window_state->IsMaximized());
468 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
469 EXPECT_FALSE(window_state->IsMaximized());
470 EXPECT_TRUE(window_state->IsMinimized());
471 window_state->Restore();
472 window_state->Activate();
475 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
476 EXPECT_TRUE(window_state->IsMinimized());
480 TEST_F(AcceleratorControllerTest, CenterWindowAccelerator) {
481 scoped_ptr<aura::Window> window(
482 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
483 const ui::Accelerator dummy;
484 wm::WindowState* window_state = wm::GetWindowState(window.get());
485 window_state->Activate();
487 // Center the window using accelerator.
488 GetController()->PerformAction(WINDOW_POSITION_CENTER, dummy);
489 gfx::Rect work_area =
490 Shell::GetScreen()->GetDisplayNearestWindow(window.get()).work_area();
491 gfx::Rect bounds = window->GetBoundsInScreen();
492 EXPECT_NEAR(bounds.x() - work_area.x(),
493 work_area.right() - bounds.right(),
495 EXPECT_NEAR(bounds.y() - work_area.y(),
496 work_area.bottom() - bounds.bottom(),
499 // Add the window to docked container and try to center it.
500 window->SetBounds(gfx::Rect(0, 0, 20, 20));
501 aura::Window* docked_container = Shell::GetContainer(
502 window->GetRootWindow(), kShellWindowId_DockedContainer);
503 docked_container->AddChild(window.get());
504 gfx::Rect docked_bounds = window->GetBoundsInScreen();
505 GetController()->PerformAction(WINDOW_POSITION_CENTER, dummy);
506 // It should not get centered and should remain docked.
507 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
508 EXPECT_EQ(docked_bounds.ToString(), window->GetBoundsInScreen().ToString());
511 TEST_F(AcceleratorControllerTest, ControllerContext) {
512 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
513 ui::Accelerator accelerator_a2(ui::VKEY_A, ui::EF_NONE);
514 ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
516 accelerator_a.set_type(ui::ET_KEY_PRESSED);
517 accelerator_a2.set_type(ui::ET_KEY_RELEASED);
518 accelerator_b.set_type(ui::ET_KEY_PRESSED);
520 EXPECT_FALSE(GetController()->context()->repeated());
521 EXPECT_EQ(ui::ET_UNKNOWN,
522 GetController()->context()->previous_accelerator().type());
524 GetController()->context()->UpdateContext(accelerator_a);
525 EXPECT_FALSE(GetController()->context()->repeated());
526 EXPECT_EQ(ui::ET_UNKNOWN,
527 GetController()->context()->previous_accelerator().type());
529 GetController()->context()->UpdateContext(accelerator_a2);
530 EXPECT_FALSE(GetController()->context()->repeated());
531 EXPECT_EQ(ui::ET_KEY_PRESSED,
532 GetController()->context()->previous_accelerator().type());
534 GetController()->context()->UpdateContext(accelerator_a2);
535 EXPECT_TRUE(GetController()->context()->repeated());
536 EXPECT_EQ(ui::ET_KEY_RELEASED,
537 GetController()->context()->previous_accelerator().type());
539 GetController()->context()->UpdateContext(accelerator_b);
540 EXPECT_FALSE(GetController()->context()->repeated());
541 EXPECT_EQ(ui::ET_KEY_RELEASED,
542 GetController()->context()->previous_accelerator().type());
545 #if defined(OS_WIN) && defined(USE_AURA)
547 #define MAYBE_SuppressToggleMaximized DISABLED_SuppressToggleMaximized
549 #define MAYBE_SuppressToggleMaximized SuppressToggleMaximized
552 TEST_F(AcceleratorControllerTest, MAYBE_SuppressToggleMaximized) {
553 scoped_ptr<aura::Window> window(
554 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
555 wm::ActivateWindow(window.get());
556 const ui::Accelerator accelerator(ui::VKEY_A, ui::EF_NONE);
557 const ui::Accelerator empty_accelerator;
559 wm::WindowState* window_state = wm::GetWindowState(window.get());
561 // Toggling not suppressed.
562 GetController()->context()->UpdateContext(accelerator);
563 GetController()->PerformAction(TOGGLE_MAXIMIZED, accelerator);
564 EXPECT_TRUE(window_state->IsMaximized());
566 // The same accelerator - toggling suppressed.
567 GetController()->context()->UpdateContext(accelerator);
568 GetController()->PerformAction(TOGGLE_MAXIMIZED, accelerator);
569 EXPECT_TRUE(window_state->IsMaximized());
571 // Suppressed but not for gesture events.
572 GetController()->PerformAction(TOGGLE_MAXIMIZED, empty_accelerator);
573 EXPECT_FALSE(window_state->IsMaximized());
576 #if defined(OS_WIN) && defined(USE_AURA)
578 #define MAYBE_ProcessOnce DISABLED_ProcessOnce
580 #define MAYBE_ProcessOnce ProcessOnce
583 #if defined(OS_WIN) || defined(USE_X11)
584 TEST_F(AcceleratorControllerTest, MAYBE_ProcessOnce) {
585 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
587 GetController()->Register(accelerator_a, &target);
589 // The accelerator is processed only once.
590 ui::EventProcessor* dispatcher =
591 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
593 MSG msg1 = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 };
594 ui::TranslatedKeyEvent key_event1(msg1, false);
595 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1);
596 EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed);
598 MSG msg2 = { NULL, WM_CHAR, L'A', 0 };
599 ui::TranslatedKeyEvent key_event2(msg2, true);
600 details = dispatcher->OnEventFromSource(&key_event2);
601 EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed);
603 MSG msg3 = { NULL, WM_KEYUP, ui::VKEY_A, 0 };
604 ui::TranslatedKeyEvent key_event3(msg3, false);
605 details = dispatcher->OnEventFromSource(&key_event3);
606 EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed);
607 #elif defined(USE_X11)
608 ui::ScopedXI2Event key_event;
609 key_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
610 ui::TranslatedKeyEvent key_event1(key_event, false);
611 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1);
612 EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed);
614 ui::TranslatedKeyEvent key_event2(key_event, true);
615 details = dispatcher->OnEventFromSource(&key_event2);
616 EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed);
618 key_event.InitKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_A, 0);
619 ui::TranslatedKeyEvent key_event3(key_event, false);
620 details = dispatcher->OnEventFromSource(&key_event3);
621 EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed);
623 EXPECT_EQ(1, target.accelerator_pressed_count());
627 TEST_F(AcceleratorControllerTest, GlobalAccelerators) {
629 EXPECT_TRUE(ProcessWithContext(
630 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
632 EXPECT_TRUE(ProcessWithContext(
633 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
635 EXPECT_TRUE(ProcessWithContext(
636 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE)));
638 #if defined(OS_CHROMEOS)
639 // Take screenshot / partial screenshot
640 // True should always be returned regardless of the existence of the delegate.
642 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
643 delegate->set_can_take_screenshot(false);
644 EXPECT_TRUE(ProcessWithContext(
645 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
646 EXPECT_TRUE(ProcessWithContext(
647 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
648 EXPECT_TRUE(ProcessWithContext(
649 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
650 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
652 delegate->set_can_take_screenshot(true);
653 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
654 EXPECT_TRUE(ProcessWithContext(
655 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
656 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
657 EXPECT_TRUE(ProcessWithContext(
658 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
659 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
660 EXPECT_TRUE(ProcessWithContext(
661 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
662 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
663 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
666 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
667 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
668 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
670 TestVolumeControlDelegate* delegate =
671 new TestVolumeControlDelegate(false);
672 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
673 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
674 EXPECT_EQ(0, delegate->handle_volume_mute_count());
675 EXPECT_FALSE(ProcessWithContext(volume_mute));
676 EXPECT_EQ(1, delegate->handle_volume_mute_count());
677 EXPECT_EQ(volume_mute, delegate->last_accelerator());
678 EXPECT_EQ(0, delegate->handle_volume_down_count());
679 EXPECT_FALSE(ProcessWithContext(volume_down));
680 EXPECT_EQ(1, delegate->handle_volume_down_count());
681 EXPECT_EQ(volume_down, delegate->last_accelerator());
682 EXPECT_EQ(0, delegate->handle_volume_up_count());
683 EXPECT_FALSE(ProcessWithContext(volume_up));
684 EXPECT_EQ(1, delegate->handle_volume_up_count());
685 EXPECT_EQ(volume_up, delegate->last_accelerator());
688 TestVolumeControlDelegate* delegate = new TestVolumeControlDelegate(true);
689 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
690 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
691 EXPECT_EQ(0, delegate->handle_volume_mute_count());
692 EXPECT_TRUE(ProcessWithContext(volume_mute));
693 EXPECT_EQ(1, delegate->handle_volume_mute_count());
694 EXPECT_EQ(volume_mute, delegate->last_accelerator());
695 EXPECT_EQ(0, delegate->handle_volume_down_count());
696 EXPECT_TRUE(ProcessWithContext(volume_down));
697 EXPECT_EQ(1, delegate->handle_volume_down_count());
698 EXPECT_EQ(volume_down, delegate->last_accelerator());
699 EXPECT_EQ(0, delegate->handle_volume_up_count());
700 EXPECT_TRUE(ProcessWithContext(volume_up));
701 EXPECT_EQ(1, delegate->handle_volume_up_count());
702 EXPECT_EQ(volume_up, delegate->last_accelerator());
704 #if defined(OS_CHROMEOS)
706 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
707 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
708 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
710 DummyBrightnessControlDelegate* delegate =
711 new DummyBrightnessControlDelegate(false);
712 GetController()->SetBrightnessControlDelegate(
713 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
714 EXPECT_EQ(0, delegate->handle_brightness_down_count());
715 EXPECT_FALSE(ProcessWithContext(brightness_down));
716 EXPECT_EQ(1, delegate->handle_brightness_down_count());
717 EXPECT_EQ(brightness_down, delegate->last_accelerator());
718 EXPECT_EQ(0, delegate->handle_brightness_up_count());
719 EXPECT_FALSE(ProcessWithContext(brightness_up));
720 EXPECT_EQ(1, delegate->handle_brightness_up_count());
721 EXPECT_EQ(brightness_up, delegate->last_accelerator());
724 DummyBrightnessControlDelegate* delegate =
725 new DummyBrightnessControlDelegate(true);
726 GetController()->SetBrightnessControlDelegate(
727 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
728 EXPECT_EQ(0, delegate->handle_brightness_down_count());
729 EXPECT_TRUE(ProcessWithContext(brightness_down));
730 EXPECT_EQ(1, delegate->handle_brightness_down_count());
731 EXPECT_EQ(brightness_down, delegate->last_accelerator());
732 EXPECT_EQ(0, delegate->handle_brightness_up_count());
733 EXPECT_TRUE(ProcessWithContext(brightness_up));
734 EXPECT_EQ(1, delegate->handle_brightness_up_count());
735 EXPECT_EQ(brightness_up, delegate->last_accelerator());
738 // Keyboard brightness
739 const ui::Accelerator alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN,
741 const ui::Accelerator alt_brightness_up(ui::VKEY_BRIGHTNESS_UP,
744 EXPECT_TRUE(ProcessWithContext(alt_brightness_down));
745 EXPECT_TRUE(ProcessWithContext(alt_brightness_up));
746 DummyKeyboardBrightnessControlDelegate* delegate =
747 new DummyKeyboardBrightnessControlDelegate(false);
748 GetController()->SetKeyboardBrightnessControlDelegate(
749 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
750 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
751 EXPECT_FALSE(ProcessWithContext(alt_brightness_down));
752 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
753 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
754 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
755 EXPECT_FALSE(ProcessWithContext(alt_brightness_up));
756 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
757 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
760 DummyKeyboardBrightnessControlDelegate* delegate =
761 new DummyKeyboardBrightnessControlDelegate(true);
762 GetController()->SetKeyboardBrightnessControlDelegate(
763 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
764 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
765 EXPECT_TRUE(ProcessWithContext(alt_brightness_down));
766 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
767 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
768 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
769 EXPECT_TRUE(ProcessWithContext(alt_brightness_up));
770 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
771 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
776 // ToggleDesktopBackgroundMode
777 EXPECT_TRUE(ProcessWithContext(
778 ui::Accelerator(ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)));
779 #if !defined(OS_LINUX)
780 // ToggleDesktopFullScreen (not implemented yet on Linux)
781 EXPECT_TRUE(ProcessWithContext(
782 ui::Accelerator(ui::VKEY_F11, ui::EF_CONTROL_DOWN)));
788 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
791 EXPECT_TRUE(is_idle(ewh));
792 EXPECT_FALSE(is_ui_shown(ewh));
793 EXPECT_TRUE(ProcessWithContext(
794 ui::Accelerator(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
795 EXPECT_FALSE(is_idle(ewh));
796 EXPECT_TRUE(is_ui_shown(ewh));
797 SimulateTimerExpired(ewh);
798 EXPECT_TRUE(is_idle(ewh));
799 EXPECT_FALSE(is_ui_shown(ewh));
804 EXPECT_TRUE(ProcessWithContext(
805 ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN)));
807 // New incognito window
808 EXPECT_TRUE(ProcessWithContext(
809 ui::Accelerator(ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
812 EXPECT_TRUE(ProcessWithContext(
813 ui::Accelerator(ui::VKEY_N, ui::EF_CONTROL_DOWN)));
816 EXPECT_TRUE(ProcessWithContext(
817 ui::Accelerator(ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
820 EXPECT_TRUE(ProcessWithContext(
821 ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN)));
823 #if defined(OS_CHROMEOS)
825 EXPECT_TRUE(ProcessWithContext(
826 ui::Accelerator(ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
829 // NOTE: Accelerators that do not work on the lock screen need to be
830 // tested before the sequence below is invoked because it causes a side
831 // effect of locking the screen.
832 EXPECT_TRUE(ProcessWithContext(
833 ui::Accelerator(ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
837 TEST_F(AcceleratorControllerTest, GlobalAcceleratorsToggleAppList) {
838 AccessibilityDelegate* delegate =
839 ash::Shell::GetInstance()->accessibility_delegate();
840 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
842 // The press event should not open the AppList, the release should instead.
843 EXPECT_FALSE(ProcessWithContext(
844 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
845 EXPECT_TRUE(ProcessWithContext(
846 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
847 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
849 // When spoken feedback is on, the AppList should not toggle.
850 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
851 EXPECT_FALSE(ProcessWithContext(
852 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
853 EXPECT_FALSE(ProcessWithContext(
854 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
855 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
856 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
858 EXPECT_FALSE(ProcessWithContext(
859 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
860 EXPECT_TRUE(ProcessWithContext(
861 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
862 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
864 // When spoken feedback is on, the AppList should not toggle.
865 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
866 EXPECT_FALSE(ProcessWithContext(
867 ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
868 EXPECT_FALSE(ProcessWithContext(
869 ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
870 delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
871 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
874 TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) {
875 // Test IME shortcuts.
877 const ui::Accelerator control_space(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
878 const ui::Accelerator convert(ui::VKEY_CONVERT, ui::EF_NONE);
879 const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, ui::EF_NONE);
880 const ui::Accelerator wide_half_1(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE);
881 const ui::Accelerator wide_half_2(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE);
882 const ui::Accelerator hangul(ui::VKEY_HANGUL, ui::EF_NONE);
883 EXPECT_FALSE(ProcessWithContext(control_space));
884 EXPECT_FALSE(ProcessWithContext(convert));
885 EXPECT_FALSE(ProcessWithContext(non_convert));
886 EXPECT_FALSE(ProcessWithContext(wide_half_1));
887 EXPECT_FALSE(ProcessWithContext(wide_half_2));
888 EXPECT_FALSE(ProcessWithContext(hangul));
889 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
890 GetController()->SetImeControlDelegate(
891 scoped_ptr<ImeControlDelegate>(delegate).Pass());
892 EXPECT_EQ(0, delegate->handle_previous_ime_count());
893 EXPECT_TRUE(ProcessWithContext(control_space));
894 EXPECT_EQ(1, delegate->handle_previous_ime_count());
895 EXPECT_EQ(0, delegate->handle_switch_ime_count());
896 EXPECT_TRUE(ProcessWithContext(convert));
897 EXPECT_EQ(1, delegate->handle_switch_ime_count());
898 EXPECT_TRUE(ProcessWithContext(non_convert));
899 EXPECT_EQ(2, delegate->handle_switch_ime_count());
900 EXPECT_TRUE(ProcessWithContext(wide_half_1));
901 EXPECT_EQ(3, delegate->handle_switch_ime_count());
902 EXPECT_TRUE(ProcessWithContext(wide_half_2));
903 EXPECT_EQ(4, delegate->handle_switch_ime_count());
904 EXPECT_TRUE(ProcessWithContext(hangul));
905 EXPECT_EQ(5, delegate->handle_switch_ime_count());
908 // Test IME shortcuts that are triggered on key release.
910 const ui::Accelerator shift_alt_press(ui::VKEY_MENU,
911 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
912 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
913 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT,
914 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
915 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
917 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
918 GetController()->SetImeControlDelegate(
919 scoped_ptr<ImeControlDelegate>(delegate).Pass());
920 EXPECT_EQ(0, delegate->handle_next_ime_count());
921 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
922 EXPECT_TRUE(ProcessWithContext(shift_alt));
923 EXPECT_EQ(1, delegate->handle_next_ime_count());
924 EXPECT_FALSE(ProcessWithContext(alt_shift_press));
925 EXPECT_TRUE(ProcessWithContext(alt_shift));
926 EXPECT_EQ(2, delegate->handle_next_ime_count());
928 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
930 const ui::Accelerator shift_alt_x_press(
932 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
933 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
934 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
936 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
937 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press));
938 EXPECT_FALSE(ProcessWithContext(shift_alt_x));
939 EXPECT_FALSE(ProcessWithContext(shift_alt));
940 EXPECT_EQ(2, delegate->handle_next_ime_count());
942 // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
943 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
944 const ui::Accelerator shift_alt_return_press(
946 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
947 const ReleaseAccelerator shift_alt_return(
949 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
951 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
952 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press));
953 EXPECT_FALSE(ProcessWithContext(shift_alt_return));
954 EXPECT_TRUE(ProcessWithContext(shift_alt));
955 EXPECT_EQ(3, delegate->handle_next_ime_count());
957 const ui::Accelerator shift_alt_space_press(
959 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
960 const ReleaseAccelerator shift_alt_space(
962 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
964 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
965 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press));
966 EXPECT_FALSE(ProcessWithContext(shift_alt_space));
967 EXPECT_TRUE(ProcessWithContext(shift_alt));
968 EXPECT_EQ(4, delegate->handle_next_ime_count());
971 #if defined(OS_CHROMEOS)
972 // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
974 const ui::Accelerator shift_alt_press(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
975 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
976 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
977 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
979 DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
980 GetController()->SetImeControlDelegate(
981 scoped_ptr<ImeControlDelegate>(delegate).Pass());
982 EXPECT_EQ(0, delegate->handle_next_ime_count());
983 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
984 EXPECT_TRUE(ProcessWithContext(shift_alt));
985 EXPECT_EQ(1, delegate->handle_next_ime_count());
986 EXPECT_FALSE(ProcessWithContext(alt_shift_press));
987 EXPECT_TRUE(ProcessWithContext(alt_shift));
988 EXPECT_EQ(2, delegate->handle_next_ime_count());
990 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
992 const ui::Accelerator shift_alt_x_press(
994 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
995 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
996 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
998 EXPECT_FALSE(ProcessWithContext(shift_alt_press));
999 EXPECT_FALSE(ProcessWithContext(shift_alt_x_press));
1000 EXPECT_FALSE(ProcessWithContext(shift_alt_x));
1001 EXPECT_FALSE(ProcessWithContext(shift_alt));
1002 EXPECT_EQ(2, delegate->handle_next_ime_count());
1007 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1008 TEST_F(AcceleratorControllerTest, ImeGlobalAcceleratorsWorkaround139556) {
1009 // The workaround for crbug.com/139556 depends on the fact that we don't
1010 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1011 const ui::Accelerator shift_alt_return_press(
1013 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1014 EXPECT_FALSE(ProcessWithContext(shift_alt_return_press));
1015 const ui::Accelerator shift_alt_space_press(
1017 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1018 EXPECT_FALSE(ProcessWithContext(shift_alt_space_press));
1021 TEST_F(AcceleratorControllerTest, ReservedAccelerators) {
1022 // (Shift+)Alt+Tab and Chrome OS top-row keys are reserved.
1023 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1024 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
1025 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1026 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
1027 #if defined(OS_CHROMEOS)
1028 EXPECT_TRUE(GetController()->IsReservedAccelerator(
1029 ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE)));
1031 // Others are not reserved.
1032 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1033 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1034 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1035 ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE)));
1036 EXPECT_FALSE(GetController()->IsReservedAccelerator(
1037 ui::Accelerator(ui::VKEY_A, ui::EF_NONE)));
1040 #if defined(OS_CHROMEOS)
1041 TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) {
1042 std::set<AcceleratorAction> all_actions;
1043 for (size_t i = 0 ; i < kAcceleratorDataLength; ++i)
1044 all_actions.insert(kAcceleratorData[i].action);
1045 #if !defined(NDEBUG)
1046 std::set<AcceleratorAction> all_desktop_actions;
1047 for (size_t i = 0 ; i < kDesktopAcceleratorDataLength; ++i)
1048 all_desktop_actions.insert(kDesktopAcceleratorData[i].action);
1051 std::set<AcceleratorAction> actionsAllowedAtModalWindow;
1052 for (size_t k = 0 ; k < kActionsAllowedAtModalWindowLength; ++k)
1053 actionsAllowedAtModalWindow.insert(kActionsAllowedAtModalWindow[k]);
1054 for (std::set<AcceleratorAction>::const_iterator it =
1055 actionsAllowedAtModalWindow.begin();
1056 it != actionsAllowedAtModalWindow.end(); ++it) {
1057 EXPECT_TRUE(all_actions.find(*it) != all_actions.end()
1059 #if !defined(NDEBUG)
1060 || all_desktop_actions.find(*it) != all_desktop_actions.end()
1063 << " action from kActionsAllowedAtModalWindow"
1064 << " not found in kAcceleratorData or kDesktopAcceleratorData. "
1065 << "action: " << *it;
1067 scoped_ptr<aura::Window> window(
1068 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1069 const ui::Accelerator dummy;
1070 wm::ActivateWindow(window.get());
1071 Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1072 for (std::set<AcceleratorAction>::const_iterator it = all_actions.begin();
1073 it != all_actions.end(); ++it) {
1074 if (actionsAllowedAtModalWindow.find(*it) ==
1075 actionsAllowedAtModalWindow.end()) {
1076 EXPECT_TRUE(GetController()->PerformAction(*it, dummy))
1077 << " for action (disallowed at modal window): " << *it;
1080 // Testing of top row (F5-F10) accelerators that should still work
1081 // when a modal window is open
1085 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
1086 delegate->set_can_take_screenshot(false);
1087 EXPECT_TRUE(ProcessWithContext(
1088 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1089 EXPECT_TRUE(ProcessWithContext(
1090 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1091 EXPECT_TRUE(ProcessWithContext(
1092 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
1093 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1094 delegate->set_can_take_screenshot(true);
1095 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
1096 EXPECT_TRUE(ProcessWithContext(
1097 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1098 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
1099 EXPECT_TRUE(ProcessWithContext(
1100 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1101 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1102 EXPECT_TRUE(ProcessWithContext(
1103 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
1104 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1105 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1108 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
1109 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
1111 DummyBrightnessControlDelegate* delegate =
1112 new DummyBrightnessControlDelegate(false);
1113 GetController()->SetBrightnessControlDelegate(
1114 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1115 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1116 EXPECT_FALSE(ProcessWithContext(brightness_down));
1117 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1118 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1119 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1120 EXPECT_FALSE(ProcessWithContext(brightness_up));
1121 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1122 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1125 DummyBrightnessControlDelegate* delegate =
1126 new DummyBrightnessControlDelegate(true);
1127 GetController()->SetBrightnessControlDelegate(
1128 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1129 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1130 EXPECT_TRUE(ProcessWithContext(brightness_down));
1131 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1132 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1133 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1134 EXPECT_TRUE(ProcessWithContext(brightness_up));
1135 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1136 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1139 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
1140 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
1141 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
1143 EXPECT_TRUE(ProcessWithContext(volume_mute));
1144 EXPECT_TRUE(ProcessWithContext(volume_down));
1145 EXPECT_TRUE(ProcessWithContext(volume_up));
1146 TestVolumeControlDelegate* delegate =
1147 new TestVolumeControlDelegate(false);
1148 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1149 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1150 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1151 EXPECT_FALSE(ProcessWithContext(volume_mute));
1152 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1153 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1154 EXPECT_EQ(0, delegate->handle_volume_down_count());
1155 EXPECT_FALSE(ProcessWithContext(volume_down));
1156 EXPECT_EQ(1, delegate->handle_volume_down_count());
1157 EXPECT_EQ(volume_down, delegate->last_accelerator());
1158 EXPECT_EQ(0, delegate->handle_volume_up_count());
1159 EXPECT_FALSE(ProcessWithContext(volume_up));
1160 EXPECT_EQ(1, delegate->handle_volume_up_count());
1161 EXPECT_EQ(volume_up, delegate->last_accelerator());
1164 TestVolumeControlDelegate* delegate = new TestVolumeControlDelegate(true);
1165 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1166 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1167 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1168 EXPECT_TRUE(ProcessWithContext(volume_mute));
1169 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1170 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1171 EXPECT_EQ(0, delegate->handle_volume_down_count());
1172 EXPECT_TRUE(ProcessWithContext(volume_down));
1173 EXPECT_EQ(1, delegate->handle_volume_down_count());
1174 EXPECT_EQ(volume_down, delegate->last_accelerator());
1175 EXPECT_EQ(0, delegate->handle_volume_up_count());
1176 EXPECT_TRUE(ProcessWithContext(volume_up));
1177 EXPECT_EQ(1, delegate->handle_volume_up_count());
1178 EXPECT_EQ(volume_up, delegate->last_accelerator());
1183 TEST_F(AcceleratorControllerTest, DisallowedWithNoWindow) {
1184 const ui::Accelerator dummy;
1185 AccessibilityDelegate* delegate =
1186 ash::Shell::GetInstance()->accessibility_delegate();
1188 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1189 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1191 GetController()->PerformAction(kActionsNeedingWindow[i], dummy));
1192 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_WINDOW_NEEDED);
1195 // Make sure we don't alert if we do have a window.
1196 scoped_ptr<aura::Window> window(
1197 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1198 wm::ActivateWindow(window.get());
1199 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1200 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1201 GetController()->PerformAction(kActionsNeedingWindow[i], dummy);
1202 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_NONE);
1205 // Don't alert if we have a minimized window either.
1206 GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
1207 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1208 delegate->TriggerAccessibilityAlert(A11Y_ALERT_NONE);
1209 GetController()->PerformAction(kActionsNeedingWindow[i], dummy);
1210 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), A11Y_ALERT_NONE);