[Ozone-Drm] Add support for async content protection
[chromium-blink-merge.git] / ash / accelerators / accelerator_controller_unittest.cc
blob1d731b3c4f3fc92831b0c20174e0ff120fcb8d2a
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_session_state_animator.h"
22 #include "ash/test/test_shelf_delegate.h"
23 #include "ash/test/test_shell_delegate.h"
24 #include "ash/test/test_volume_control_delegate.h"
25 #include "ash/volume_control_delegate.h"
26 #include "ash/wm/lock_state_controller.h"
27 #include "ash/wm/panels/panel_layout_manager.h"
28 #include "ash/wm/window_state.h"
29 #include "ash/wm/window_util.h"
30 #include "ash/wm/wm_event.h"
31 #include "base/command_line.h"
32 #include "ui/aura/client/aura_constants.h"
33 #include "ui/aura/test/test_window_delegate.h"
34 #include "ui/aura/test/test_windows.h"
35 #include "ui/aura/window.h"
36 #include "ui/events/event.h"
37 #include "ui/events/event_processor.h"
38 #include "ui/events/test/event_generator.h"
39 #include "ui/gfx/screen.h"
40 #include "ui/views/widget/widget.h"
42 #if defined(USE_X11)
43 #include <X11/Xlib.h>
44 #include "ui/events/test/events_test_utils_x11.h"
45 #endif
47 namespace ash {
49 namespace {
51 class TestTarget : public ui::AcceleratorTarget {
52 public:
53 TestTarget() : accelerator_pressed_count_(0), accelerator_repeat_count_(0) {}
54 ~TestTarget() override {}
56 int accelerator_pressed_count() const {
57 return accelerator_pressed_count_;
60 int accelerator_repeat_count() const { return accelerator_repeat_count_; }
62 void reset() {
63 accelerator_pressed_count_ = 0;
64 accelerator_repeat_count_ = 0;
67 // Overridden from ui::AcceleratorTarget:
68 bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
69 bool CanHandleAccelerators() const override;
71 private:
72 int accelerator_pressed_count_;
73 int accelerator_repeat_count_;
75 DISALLOW_COPY_AND_ASSIGN(TestTarget);
78 class ReleaseAccelerator : public ui::Accelerator {
79 public:
80 ReleaseAccelerator(ui::KeyboardCode keycode, int modifiers)
81 : ui::Accelerator(keycode, modifiers) {
82 set_type(ui::ET_KEY_RELEASED);
86 class DummyBrightnessControlDelegate : public BrightnessControlDelegate {
87 public:
88 DummyBrightnessControlDelegate()
89 : handle_brightness_down_count_(0), handle_brightness_up_count_(0) {}
90 ~DummyBrightnessControlDelegate() override {}
92 void HandleBrightnessDown(const ui::Accelerator& accelerator) override {
93 ++handle_brightness_down_count_;
94 last_accelerator_ = accelerator;
96 void HandleBrightnessUp(const ui::Accelerator& accelerator) override {
97 ++handle_brightness_up_count_;
98 last_accelerator_ = accelerator;
100 void SetBrightnessPercent(double percent, bool gradual) override {}
101 void GetBrightnessPercent(
102 const base::Callback<void(double)>& callback) override {
103 callback.Run(100.0);
106 int handle_brightness_down_count() const {
107 return handle_brightness_down_count_;
109 int handle_brightness_up_count() const {
110 return handle_brightness_up_count_;
112 const ui::Accelerator& last_accelerator() const {
113 return last_accelerator_;
116 private:
117 int handle_brightness_down_count_;
118 int handle_brightness_up_count_;
119 ui::Accelerator last_accelerator_;
121 DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate);
124 class DummyImeControlDelegate : public ImeControlDelegate {
125 public:
126 DummyImeControlDelegate()
127 : handle_next_ime_count_(0),
128 handle_previous_ime_count_(0),
129 handle_switch_ime_count_(0) {}
130 ~DummyImeControlDelegate() override {}
132 bool CanCycleIme() override { return true; }
133 void HandleNextIme() override { ++handle_next_ime_count_; }
134 void HandlePreviousIme() override {
135 ++handle_previous_ime_count_;
137 bool CanSwitchIme(const ui::Accelerator& accelerator) override {
138 return true;
140 void HandleSwitchIme(const ui::Accelerator& accelerator) override {
141 ++handle_switch_ime_count_;
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 ui::Accelerator RemapAccelerator(
154 const ui::Accelerator& accelerator) override {
155 return ui::Accelerator(accelerator);
158 private:
159 int handle_next_ime_count_;
160 int handle_previous_ime_count_;
161 int handle_switch_ime_count_;
163 DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate);
166 class DummyKeyboardBrightnessControlDelegate
167 : public KeyboardBrightnessControlDelegate {
168 public:
169 DummyKeyboardBrightnessControlDelegate()
170 : handle_keyboard_brightness_down_count_(0),
171 handle_keyboard_brightness_up_count_(0) {}
172 ~DummyKeyboardBrightnessControlDelegate() override {}
174 void HandleKeyboardBrightnessDown(
175 const ui::Accelerator& accelerator) override {
176 ++handle_keyboard_brightness_down_count_;
177 last_accelerator_ = accelerator;
180 void HandleKeyboardBrightnessUp(const ui::Accelerator& accelerator) override {
181 ++handle_keyboard_brightness_up_count_;
182 last_accelerator_ = accelerator;
185 int handle_keyboard_brightness_down_count() const {
186 return handle_keyboard_brightness_down_count_;
189 int handle_keyboard_brightness_up_count() const {
190 return handle_keyboard_brightness_up_count_;
193 const ui::Accelerator& last_accelerator() const {
194 return last_accelerator_;
197 private:
198 int handle_keyboard_brightness_down_count_;
199 int handle_keyboard_brightness_up_count_;
200 ui::Accelerator last_accelerator_;
202 DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate);
205 bool TestTarget::AcceleratorPressed(const ui::Accelerator& accelerator) {
206 if (accelerator.IsRepeat())
207 ++accelerator_repeat_count_;
208 else
209 ++accelerator_pressed_count_;
210 return true;
213 bool TestTarget::CanHandleAccelerators() const {
214 return true;
217 } // namespace
219 class AcceleratorControllerTest : public test::AshTestBase {
220 public:
221 AcceleratorControllerTest() {}
222 ~AcceleratorControllerTest() override {}
224 protected:
225 void EnableInternalDisplay() {
226 test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
227 SetFirstDisplayAsInternalDisplay();
230 static AcceleratorController* GetController();
232 static bool ProcessInController(const ui::Accelerator& accelerator) {
233 GetController()->accelerator_history()->
234 StoreCurrentAccelerator(accelerator);
235 return GetController()->Process(accelerator);
238 static const ui::Accelerator& GetPreviousAccelerator() {
239 return GetController()->accelerator_history()->
240 previous_accelerator();
243 static const ui::Accelerator& GetCurrentAccelerator() {
244 return GetController()->accelerator_history()->
245 current_accelerator();
248 // Several functions to access ExitWarningHandler (as friend).
249 static void StubForTest(ExitWarningHandler* ewh) {
250 ewh->stub_timer_for_test_ = true;
252 static void Reset(ExitWarningHandler* ewh) {
253 ewh->state_ = ExitWarningHandler::IDLE;
255 static void SimulateTimerExpired(ExitWarningHandler* ewh) {
256 ewh->TimerAction();
258 static bool is_ui_shown(ExitWarningHandler* ewh) {
259 return !!ewh->widget_;
261 static bool is_idle(ExitWarningHandler* ewh) {
262 return ewh->state_ == ExitWarningHandler::IDLE;
264 static bool is_exiting(ExitWarningHandler* ewh) {
265 return ewh->state_ == ExitWarningHandler::EXITING;
267 aura::Window* CreatePanel() {
268 aura::Window* window =
269 CreateTestWindowInShellWithDelegateAndType(NULL,
270 ui::wm::WINDOW_TYPE_PANEL, 0, gfx::Rect(5, 5, 20, 20));
271 test::TestShelfDelegate* shelf_delegate =
272 test::TestShelfDelegate::instance();
273 shelf_delegate->AddShelfItem(window);
274 PanelLayoutManager* manager = static_cast<PanelLayoutManager*>(
275 Shell::GetContainer(window->GetRootWindow(),
276 kShellWindowId_PanelContainer)->layout_manager());
277 manager->Relayout();
278 return window;
281 private:
282 DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest);
285 AcceleratorController* AcceleratorControllerTest::GetController() {
286 return Shell::GetInstance()->accelerator_controller();
289 #if !defined(OS_WIN)
290 // Double press of exit shortcut => exiting
291 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) {
292 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
293 ui::Accelerator release(press);
294 release.set_type(ui::ET_KEY_RELEASED);
295 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
296 ASSERT_TRUE(!!ewh);
297 StubForTest(ewh);
298 EXPECT_TRUE(is_idle(ewh));
299 EXPECT_FALSE(is_ui_shown(ewh));
300 EXPECT_TRUE(ProcessInController(press));
301 EXPECT_FALSE(ProcessInController(release));
302 EXPECT_FALSE(is_idle(ewh));
303 EXPECT_TRUE(is_ui_shown(ewh));
304 EXPECT_TRUE(ProcessInController(press)); // second press before timer.
305 EXPECT_FALSE(ProcessInController(release));
306 SimulateTimerExpired(ewh);
307 EXPECT_TRUE(is_exiting(ewh));
308 EXPECT_FALSE(is_ui_shown(ewh));
309 Reset(ewh);
312 // Single press of exit shortcut before timer => idle
313 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) {
314 ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
315 ui::Accelerator release(press);
316 release.set_type(ui::ET_KEY_RELEASED);
317 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
318 ASSERT_TRUE(!!ewh);
319 StubForTest(ewh);
320 EXPECT_TRUE(is_idle(ewh));
321 EXPECT_FALSE(is_ui_shown(ewh));
322 EXPECT_TRUE(ProcessInController(press));
323 EXPECT_FALSE(ProcessInController(release));
324 EXPECT_FALSE(is_idle(ewh));
325 EXPECT_TRUE(is_ui_shown(ewh));
326 SimulateTimerExpired(ewh);
327 EXPECT_TRUE(is_idle(ewh));
328 EXPECT_FALSE(is_ui_shown(ewh));
329 Reset(ewh);
332 // Shutdown ash with exit warning bubble open should not crash.
333 TEST_F(AcceleratorControllerTest, LingeringExitWarningBubble) {
334 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
335 ASSERT_TRUE(!!ewh);
336 StubForTest(ewh);
338 // Trigger once to show the bubble.
339 ewh->HandleAccelerator();
340 EXPECT_FALSE(is_idle(ewh));
341 EXPECT_TRUE(is_ui_shown(ewh));
343 // Exit ash and there should be no crash
345 #endif // !defined(OS_WIN)
347 TEST_F(AcceleratorControllerTest, Register) {
348 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
349 TestTarget target;
350 GetController()->Register(accelerator_a, &target);
352 // The registered accelerator is processed.
353 EXPECT_TRUE(ProcessInController(accelerator_a));
354 EXPECT_EQ(1, target.accelerator_pressed_count());
357 TEST_F(AcceleratorControllerTest, RegisterMultipleTarget) {
358 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
359 TestTarget target1;
360 GetController()->Register(accelerator_a, &target1);
361 TestTarget target2;
362 GetController()->Register(accelerator_a, &target2);
364 // If multiple targets are registered with the same accelerator, the target
365 // registered later processes the accelerator.
366 EXPECT_TRUE(ProcessInController(accelerator_a));
367 EXPECT_EQ(0, target1.accelerator_pressed_count());
368 EXPECT_EQ(1, target2.accelerator_pressed_count());
371 TEST_F(AcceleratorControllerTest, Unregister) {
372 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
373 TestTarget target;
374 GetController()->Register(accelerator_a, &target);
375 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
376 GetController()->Register(accelerator_b, &target);
378 // Unregistering a different accelerator does not affect the other
379 // accelerator.
380 GetController()->Unregister(accelerator_b, &target);
381 EXPECT_TRUE(ProcessInController(accelerator_a));
382 EXPECT_EQ(1, target.accelerator_pressed_count());
384 // The unregistered accelerator is no longer processed.
385 target.reset();
386 GetController()->Unregister(accelerator_a, &target);
387 EXPECT_FALSE(ProcessInController(accelerator_a));
388 EXPECT_EQ(0, target.accelerator_pressed_count());
391 TEST_F(AcceleratorControllerTest, UnregisterAll) {
392 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
393 TestTarget target1;
394 GetController()->Register(accelerator_a, &target1);
395 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
396 GetController()->Register(accelerator_b, &target1);
397 const ui::Accelerator accelerator_c(ui::VKEY_C, ui::EF_NONE);
398 TestTarget target2;
399 GetController()->Register(accelerator_c, &target2);
400 GetController()->UnregisterAll(&target1);
402 // All the accelerators registered for |target1| are no longer processed.
403 EXPECT_FALSE(ProcessInController(accelerator_a));
404 EXPECT_FALSE(ProcessInController(accelerator_b));
405 EXPECT_EQ(0, target1.accelerator_pressed_count());
407 // UnregisterAll with a different target does not affect the other target.
408 EXPECT_TRUE(ProcessInController(accelerator_c));
409 EXPECT_EQ(1, target2.accelerator_pressed_count());
412 TEST_F(AcceleratorControllerTest, Process) {
413 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
414 TestTarget target1;
415 GetController()->Register(accelerator_a, &target1);
417 // The registered accelerator is processed.
418 EXPECT_TRUE(ProcessInController(accelerator_a));
419 EXPECT_EQ(1, target1.accelerator_pressed_count());
421 // The non-registered accelerator is not processed.
422 const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
423 EXPECT_FALSE(ProcessInController(accelerator_b));
426 TEST_F(AcceleratorControllerTest, IsRegistered) {
427 const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
428 const ui::Accelerator accelerator_shift_a(ui::VKEY_A, ui::EF_SHIFT_DOWN);
429 TestTarget target;
430 GetController()->Register(accelerator_a, &target);
431 EXPECT_TRUE(GetController()->IsRegistered(accelerator_a));
432 EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a));
433 GetController()->UnregisterAll(&target);
434 EXPECT_FALSE(GetController()->IsRegistered(accelerator_a));
437 TEST_F(AcceleratorControllerTest, WindowSnap) {
438 scoped_ptr<aura::Window> window(
439 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
440 wm::WindowState* window_state = wm::GetWindowState(window.get());
442 window_state->Activate();
445 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
446 gfx::Rect expected_bounds = wm::GetDefaultLeftSnappedWindowBoundsInParent(
447 window.get());
448 EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString());
451 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT);
452 gfx::Rect expected_bounds = wm::GetDefaultRightSnappedWindowBoundsInParent(
453 window.get());
454 EXPECT_EQ(expected_bounds.ToString(), window->bounds().ToString());
457 gfx::Rect normal_bounds = window_state->GetRestoreBoundsInParent();
459 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED);
460 EXPECT_TRUE(window_state->IsMaximized());
461 EXPECT_NE(normal_bounds.ToString(), window->bounds().ToString());
463 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED);
464 EXPECT_FALSE(window_state->IsMaximized());
465 // Window gets restored to its restore bounds since side-maximized state
466 // is treated as a "maximized" state.
467 EXPECT_EQ(normal_bounds.ToString(), window->bounds().ToString());
469 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED);
470 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
471 EXPECT_FALSE(window_state->IsMaximized());
473 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED);
474 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT);
475 EXPECT_FALSE(window_state->IsMaximized());
477 GetController()->PerformActionIfEnabled(TOGGLE_MAXIMIZED);
478 EXPECT_TRUE(window_state->IsMaximized());
479 GetController()->PerformActionIfEnabled(WINDOW_MINIMIZE);
480 EXPECT_FALSE(window_state->IsMaximized());
481 EXPECT_TRUE(window_state->IsMinimized());
482 window_state->Restore();
483 window_state->Activate();
486 GetController()->PerformActionIfEnabled(WINDOW_MINIMIZE);
487 EXPECT_TRUE(window_state->IsMinimized());
491 TEST_F(AcceleratorControllerTest, WindowSnapLeftDockLeftRestore) {
492 scoped_ptr<aura::Window> window0(
493 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
494 scoped_ptr<aura::Window> window1(
495 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
496 wm::WindowState* window1_state = wm::GetWindowState(window1.get());
497 window1_state->Activate();
499 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
500 gfx::Rect normal_bounds = window1_state->GetRestoreBoundsInParent();
501 gfx::Rect expected_bounds = wm::GetDefaultLeftSnappedWindowBoundsInParent(
502 window1.get());
503 EXPECT_EQ(expected_bounds.ToString(), window1->bounds().ToString());
504 EXPECT_TRUE(window1_state->IsSnapped());
505 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
506 EXPECT_FALSE(window1_state->IsNormalOrSnapped());
507 EXPECT_TRUE(window1_state->IsDocked());
508 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
509 EXPECT_FALSE(window1_state->IsDocked());
510 EXPECT_EQ(normal_bounds.ToString(), window1->bounds().ToString());
513 TEST_F(AcceleratorControllerTest, WindowSnapRightDockRightRestore) {
514 scoped_ptr<aura::Window> window0(
515 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
516 scoped_ptr<aura::Window> window1(
517 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
519 wm::WindowState* window1_state = wm::GetWindowState(window1.get());
520 window1_state->Activate();
522 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT);
523 gfx::Rect normal_bounds = window1_state->GetRestoreBoundsInParent();
524 gfx::Rect expected_bounds =
525 wm::GetDefaultRightSnappedWindowBoundsInParent(window1.get());
526 EXPECT_EQ(expected_bounds.ToString(), window1->bounds().ToString());
527 EXPECT_TRUE(window1_state->IsSnapped());
528 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT);
529 EXPECT_FALSE(window1_state->IsNormalOrSnapped());
530 EXPECT_TRUE(window1_state->IsDocked());
531 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT);
532 EXPECT_FALSE(window1_state->IsDocked());
533 EXPECT_EQ(normal_bounds.ToString(), window1->bounds().ToString());
536 TEST_F(AcceleratorControllerTest, WindowSnapLeftDockLeftSnapRight) {
537 scoped_ptr<aura::Window> window0(
538 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
539 scoped_ptr<aura::Window> window1(
540 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
542 wm::WindowState* window1_state = wm::GetWindowState(window1.get());
543 window1_state->Activate();
545 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
546 gfx::Rect expected_bounds =
547 wm::GetDefaultLeftSnappedWindowBoundsInParent(window1.get());
548 gfx::Rect expected_bounds2 =
549 wm::GetDefaultRightSnappedWindowBoundsInParent(window1.get());
550 EXPECT_EQ(expected_bounds.ToString(), window1->bounds().ToString());
551 EXPECT_TRUE(window1_state->IsSnapped());
552 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
553 EXPECT_FALSE(window1_state->IsNormalOrSnapped());
554 EXPECT_TRUE(window1_state->IsDocked());
555 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT);
556 EXPECT_FALSE(window1_state->IsDocked());
557 EXPECT_TRUE(window1_state->IsSnapped());
558 EXPECT_EQ(expected_bounds2.ToString(), window1->bounds().ToString());
561 TEST_F(AcceleratorControllerTest, WindowDockLeftMinimizeWindowWithRestore) {
562 scoped_ptr<aura::Window> window0(
563 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
564 scoped_ptr<aura::Window> window1(
565 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
567 wm::WindowState* window1_state = wm::GetWindowState(window1.get());
568 window1_state->Activate();
570 scoped_ptr<aura::Window> window2(
571 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
573 wm::WindowState* window2_state = wm::GetWindowState(window2.get());
575 scoped_ptr<aura::Window> window3(
576 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
578 wm::WindowState* window3_state = wm::GetWindowState(window3.get());
579 window3_state->Activate();
581 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
582 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
583 gfx::Rect window3_docked_bounds = window3->bounds();
585 window2_state->Activate();
586 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
587 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
588 window1_state->Activate();
589 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
590 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
592 EXPECT_TRUE(window3_state->IsDocked());
593 EXPECT_TRUE(window2_state->IsDocked());
594 EXPECT_TRUE(window1_state->IsDocked());
595 EXPECT_TRUE(window3_state->IsMinimized());
597 window1_state->Activate();
598 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
599 window2_state->Activate();
600 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
601 window3_state->Unminimize();
602 EXPECT_FALSE(window1_state->IsDocked());
603 EXPECT_FALSE(window2_state->IsDocked());
604 EXPECT_TRUE(window3_state->IsDocked());
605 EXPECT_EQ(window3_docked_bounds.ToString(), window3->bounds().ToString());
608 TEST_F(AcceleratorControllerTest, WindowPanelDockLeftDockRightRestore) {
609 scoped_ptr<aura::Window> window0(
610 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
612 scoped_ptr<aura::Window> window(CreatePanel());
613 wm::WindowState* window_state = wm::GetWindowState(window.get());
614 window_state->Activate();
616 gfx::Rect window_restore_bounds2 = window->bounds();
617 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_LEFT);
618 gfx::Rect expected_bounds =
619 wm::GetDefaultLeftSnappedWindowBoundsInParent(window.get());
620 gfx::Rect window_restore_bounds =
621 window_state->GetRestoreBoundsInScreen();
622 EXPECT_NE(expected_bounds.ToString(), window->bounds().ToString());
623 EXPECT_FALSE(window_state->IsSnapped());
624 EXPECT_FALSE(window_state->IsNormalOrSnapped());
625 EXPECT_TRUE(window_state->IsDocked());
626 window_state->Restore();
627 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT);
628 EXPECT_TRUE(window_state->IsDocked());
629 GetController()->PerformActionIfEnabled(WINDOW_CYCLE_SNAP_DOCK_RIGHT);
630 EXPECT_FALSE(window_state->IsDocked());
631 EXPECT_EQ(window_restore_bounds.ToString(),
632 window_restore_bounds2.ToString());
633 EXPECT_EQ(window_restore_bounds.ToString(), window->bounds().ToString());
636 TEST_F(AcceleratorControllerTest, CenterWindowAccelerator) {
637 scoped_ptr<aura::Window> window(
638 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
639 wm::WindowState* window_state = wm::GetWindowState(window.get());
640 window_state->Activate();
642 // Center the window using accelerator.
643 GetController()->PerformActionIfEnabled(WINDOW_POSITION_CENTER);
644 gfx::Rect work_area =
645 Shell::GetScreen()->GetDisplayNearestWindow(window.get()).work_area();
646 gfx::Rect bounds = window->GetBoundsInScreen();
647 EXPECT_NEAR(bounds.x() - work_area.x(),
648 work_area.right() - bounds.right(),
650 EXPECT_NEAR(bounds.y() - work_area.y(),
651 work_area.bottom() - bounds.bottom(),
654 // Add the window to docked container and try to center it.
655 window->SetBounds(gfx::Rect(0, 0, 20, 20));
656 const wm::WMEvent event(wm::WM_EVENT_DOCK);
657 wm::GetWindowState(window.get())->OnWMEvent(&event);
658 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
660 gfx::Rect docked_bounds = window->GetBoundsInScreen();
661 GetController()->PerformActionIfEnabled(WINDOW_POSITION_CENTER);
662 // It should not get centered and should remain docked.
663 EXPECT_EQ(kShellWindowId_DockedContainer, window->parent()->id());
664 EXPECT_EQ(docked_bounds.ToString(), window->GetBoundsInScreen().ToString());
667 TEST_F(AcceleratorControllerTest, AutoRepeat) {
668 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_CONTROL_DOWN);
669 accelerator_a.set_type(ui::ET_KEY_PRESSED);
670 TestTarget target_a;
671 GetController()->Register(accelerator_a, &target_a);
672 ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_CONTROL_DOWN);
673 accelerator_b.set_type(ui::ET_KEY_PRESSED);
674 TestTarget target_b;
675 GetController()->Register(accelerator_b, &target_b);
677 ui::test::EventGenerator& generator = GetEventGenerator();
678 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
679 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
681 EXPECT_EQ(1, target_a.accelerator_pressed_count());
682 EXPECT_EQ(0, target_a.accelerator_repeat_count());
684 // Long press should generate one
685 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
686 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
687 EXPECT_EQ(2, target_a.accelerator_pressed_count());
688 EXPECT_EQ(1, target_a.accelerator_repeat_count());
689 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
690 EXPECT_EQ(2, target_a.accelerator_pressed_count());
691 EXPECT_EQ(2, target_a.accelerator_repeat_count());
692 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
693 EXPECT_EQ(2, target_a.accelerator_pressed_count());
694 EXPECT_EQ(2, target_a.accelerator_repeat_count());
696 // Long press was intercepted by another key press.
697 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
698 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
699 generator.PressKey(ui::VKEY_B, ui::EF_CONTROL_DOWN);
700 generator.ReleaseKey(ui::VKEY_B, ui::EF_CONTROL_DOWN);
701 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
702 generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_IS_REPEAT);
703 generator.ReleaseKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
705 EXPECT_EQ(1, target_b.accelerator_pressed_count());
706 EXPECT_EQ(0, target_b.accelerator_repeat_count());
707 EXPECT_EQ(4, target_a.accelerator_pressed_count());
708 EXPECT_EQ(4, target_a.accelerator_repeat_count());
711 TEST_F(AcceleratorControllerTest, Previous) {
712 ui::test::EventGenerator& generator = GetEventGenerator();
713 generator.PressKey(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
714 generator.ReleaseKey(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
716 EXPECT_EQ(ui::VKEY_VOLUME_MUTE,
717 GetPreviousAccelerator().key_code());
718 EXPECT_EQ(ui::EF_NONE,
719 GetPreviousAccelerator().modifiers());
721 generator.PressKey(ui::VKEY_TAB, ui::EF_CONTROL_DOWN);
722 generator.ReleaseKey(ui::VKEY_TAB, ui::EF_CONTROL_DOWN);
724 EXPECT_EQ(ui::VKEY_TAB,
725 GetPreviousAccelerator().key_code());
726 EXPECT_EQ(ui::EF_CONTROL_DOWN,
727 GetPreviousAccelerator().modifiers());
730 TEST_F(AcceleratorControllerTest, DontRepeatToggleFullscreen) {
731 const AcceleratorData accelerators[] = {
732 {true, ui::VKEY_J, ui::EF_ALT_DOWN, TOGGLE_FULLSCREEN},
733 {true, ui::VKEY_K, ui::EF_ALT_DOWN, TOGGLE_FULLSCREEN},
735 GetController()->RegisterAccelerators(accelerators, arraysize(accelerators));
737 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
738 params.context = CurrentContext();
739 params.bounds = gfx::Rect(5, 5, 20, 20);
740 views::Widget* widget = new views::Widget;
741 widget->Init(params);
742 widget->Show();
743 widget->Activate();
744 widget->GetNativeView()->SetProperty(aura::client::kCanMaximizeKey, true);
746 ui::test::EventGenerator& generator = GetEventGenerator();
747 wm::WindowState* window_state = wm::GetWindowState(widget->GetNativeView());
749 // Toggling not suppressed.
750 generator.PressKey(ui::VKEY_J, ui::EF_ALT_DOWN);
751 EXPECT_TRUE(window_state->IsFullscreen());
753 // The same accelerator - toggling suppressed.
754 generator.PressKey(ui::VKEY_J, ui::EF_ALT_DOWN | ui::EF_IS_REPEAT);
755 EXPECT_TRUE(window_state->IsFullscreen());
757 // Different accelerator.
758 generator.PressKey(ui::VKEY_K, ui::EF_ALT_DOWN);
759 EXPECT_FALSE(window_state->IsFullscreen());
762 // TODO(oshima): Fix this test to use EventGenerator.
763 #if defined(OS_WIN)
764 // crbug.com/317592
765 #define MAYBE_ProcessOnce DISABLED_ProcessOnce
766 #else
767 #define MAYBE_ProcessOnce ProcessOnce
768 #endif
770 #if defined(OS_WIN) || defined(USE_X11)
771 TEST_F(AcceleratorControllerTest, MAYBE_ProcessOnce) {
772 ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
773 TestTarget target;
774 GetController()->Register(accelerator_a, &target);
776 // The accelerator is processed only once.
777 ui::EventProcessor* dispatcher =
778 Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
779 #if defined(OS_WIN)
780 MSG msg1 = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 };
781 ui::KeyEvent key_event1(msg1);
782 key_event1.SetTranslated(true);
783 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1);
784 EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed);
786 MSG msg2 = { NULL, WM_CHAR, L'A', 0 };
787 ui::KeyEvent key_event2(msg2);
788 key_event2.SetTranslated(true);
789 details = dispatcher->OnEventFromSource(&key_event2);
790 EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed);
792 MSG msg3 = { NULL, WM_KEYUP, ui::VKEY_A, 0 };
793 ui::KeyEvent key_event3(msg3);
794 key_event3.SetTranslated(true);
795 details = dispatcher->OnEventFromSource(&key_event3);
796 EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed);
797 #elif defined(USE_X11)
798 ui::ScopedXI2Event key_event;
799 key_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
800 ui::KeyEvent key_event1(key_event);
801 key_event1.SetTranslated(true);
802 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1);
803 EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed);
805 ui::KeyEvent key_event2('A', ui::VKEY_A, ui::EF_NONE);
806 key_event2.SetTranslated(true);
807 details = dispatcher->OnEventFromSource(&key_event2);
808 EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed);
810 key_event.InitKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_A, 0);
811 ui::KeyEvent key_event3(key_event);
812 key_event3.SetTranslated(true);
813 details = dispatcher->OnEventFromSource(&key_event3);
814 EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed);
815 #endif
816 EXPECT_EQ(1, target.accelerator_pressed_count());
818 #endif
820 TEST_F(AcceleratorControllerTest, GlobalAccelerators) {
821 // CycleBackward
822 EXPECT_TRUE(ProcessInController(
823 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
824 // CycleForward
825 EXPECT_TRUE(
826 ProcessInController(ui::Accelerator(
827 ui::VKEY_TAB, ui::EF_ALT_DOWN)));
828 // CycleLinear
829 EXPECT_TRUE(ProcessInController(
830 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE)));
832 #if defined(OS_CHROMEOS)
833 // The "Take Screenshot", "Take Partial Screenshot", volume, brightness, and
834 // keyboard brightness accelerators are only defined on ChromeOS.
836 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
837 delegate->set_can_take_screenshot(false);
838 EXPECT_TRUE(ProcessInController(
839 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
840 EXPECT_TRUE(
841 ProcessInController(ui::Accelerator(
842 ui::VKEY_PRINT, ui::EF_NONE)));
843 EXPECT_TRUE(ProcessInController(ui::Accelerator(
844 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
846 delegate->set_can_take_screenshot(true);
847 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
848 EXPECT_TRUE(ProcessInController(
849 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
850 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
851 EXPECT_TRUE(
852 ProcessInController(ui::Accelerator(
853 ui::VKEY_PRINT, ui::EF_NONE)));
854 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
855 EXPECT_TRUE(ProcessInController(ui::Accelerator(
856 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
857 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
859 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
860 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
861 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
863 TestVolumeControlDelegate* delegate = new TestVolumeControlDelegate;
864 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
865 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
866 EXPECT_EQ(0, delegate->handle_volume_mute_count());
867 EXPECT_TRUE(ProcessInController(volume_mute));
868 EXPECT_EQ(1, delegate->handle_volume_mute_count());
869 EXPECT_EQ(volume_mute, delegate->last_accelerator());
870 EXPECT_EQ(0, delegate->handle_volume_down_count());
871 EXPECT_TRUE(ProcessInController(volume_down));
872 EXPECT_EQ(1, delegate->handle_volume_down_count());
873 EXPECT_EQ(volume_down, delegate->last_accelerator());
874 EXPECT_EQ(0, delegate->handle_volume_up_count());
875 EXPECT_TRUE(ProcessInController(volume_up));
876 EXPECT_EQ(1, delegate->handle_volume_up_count());
877 EXPECT_EQ(volume_up, delegate->last_accelerator());
879 // Brightness
880 // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
881 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
882 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
884 DummyBrightnessControlDelegate* delegate =
885 new DummyBrightnessControlDelegate;
886 GetController()->SetBrightnessControlDelegate(
887 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
888 EXPECT_EQ(0, delegate->handle_brightness_down_count());
889 EXPECT_TRUE(ProcessInController(brightness_down));
890 EXPECT_EQ(1, delegate->handle_brightness_down_count());
891 EXPECT_EQ(brightness_down, delegate->last_accelerator());
892 EXPECT_EQ(0, delegate->handle_brightness_up_count());
893 EXPECT_TRUE(ProcessInController(brightness_up));
894 EXPECT_EQ(1, delegate->handle_brightness_up_count());
895 EXPECT_EQ(brightness_up, delegate->last_accelerator());
898 // Keyboard brightness
899 const ui::Accelerator alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN,
900 ui::EF_ALT_DOWN);
901 const ui::Accelerator alt_brightness_up(ui::VKEY_BRIGHTNESS_UP,
902 ui::EF_ALT_DOWN);
904 EXPECT_TRUE(ProcessInController(alt_brightness_down));
905 EXPECT_TRUE(ProcessInController(alt_brightness_up));
906 DummyKeyboardBrightnessControlDelegate* delegate =
907 new DummyKeyboardBrightnessControlDelegate;
908 GetController()->SetKeyboardBrightnessControlDelegate(
909 scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
910 EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
911 EXPECT_TRUE(ProcessInController(alt_brightness_down));
912 EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
913 EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
914 EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
915 EXPECT_TRUE(ProcessInController(alt_brightness_up));
916 EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
917 EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
919 #endif
921 #if !defined(OS_WIN)
922 // Exit
923 ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
924 ASSERT_TRUE(!!ewh);
925 StubForTest(ewh);
926 EXPECT_TRUE(is_idle(ewh));
927 EXPECT_FALSE(is_ui_shown(ewh));
928 EXPECT_TRUE(ProcessInController(
929 ui::Accelerator(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
930 EXPECT_FALSE(is_idle(ewh));
931 EXPECT_TRUE(is_ui_shown(ewh));
932 SimulateTimerExpired(ewh);
933 EXPECT_TRUE(is_idle(ewh));
934 EXPECT_FALSE(is_ui_shown(ewh));
935 Reset(ewh);
936 #endif
938 // New tab
939 EXPECT_TRUE(ProcessInController(
940 ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN)));
942 // New incognito window
943 EXPECT_TRUE(ProcessInController(
944 ui::Accelerator(ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
946 // New window
947 EXPECT_TRUE(ProcessInController(
948 ui::Accelerator(ui::VKEY_N, ui::EF_CONTROL_DOWN)));
950 // Restore tab
951 EXPECT_TRUE(ProcessInController(
952 ui::Accelerator(ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
954 // Show task manager
955 EXPECT_TRUE(ProcessInController(
956 ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN)));
958 #if defined(OS_CHROMEOS)
959 // Open file manager
960 EXPECT_TRUE(ProcessInController(
961 ui::Accelerator(ui::VKEY_M, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
963 // Lock screen
964 // NOTE: Accelerators that do not work on the lock screen need to be
965 // tested before the sequence below is invoked because it causes a side
966 // effect of locking the screen.
967 EXPECT_TRUE(ProcessInController(
968 ui::Accelerator(ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
969 #endif
972 TEST_F(AcceleratorControllerTest, GlobalAcceleratorsToggleAppList) {
973 AccessibilityDelegate* delegate =
974 ash::Shell::GetInstance()->accessibility_delegate();
975 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
977 // The press event should not open the AppList, the release should instead.
978 EXPECT_FALSE(
979 ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
980 EXPECT_EQ(ui::VKEY_LWIN,
981 GetCurrentAccelerator().key_code());
983 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
985 EXPECT_TRUE(
986 ProcessInController(ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
987 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
989 EXPECT_EQ(ui::VKEY_LWIN,
990 GetPreviousAccelerator().key_code());
992 // When spoken feedback is on, the AppList should not toggle.
993 delegate->ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_NONE);
994 EXPECT_FALSE(
995 ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
996 EXPECT_FALSE(
997 ProcessInController(ReleaseAccelerator(
998 ui::VKEY_LWIN, ui::EF_NONE)));
999 delegate->ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_NONE);
1000 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1002 EXPECT_FALSE(
1003 ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
1004 EXPECT_TRUE(
1005 ProcessInController(ReleaseAccelerator(
1006 ui::VKEY_LWIN, ui::EF_NONE)));
1007 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1009 // When spoken feedback is on, the AppList should not toggle.
1010 delegate->ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_NONE);
1011 EXPECT_FALSE(
1012 ProcessInController(ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
1013 EXPECT_FALSE(
1014 ProcessInController(ReleaseAccelerator(
1015 ui::VKEY_LWIN, ui::EF_NONE)));
1016 delegate->ToggleSpokenFeedback(ui::A11Y_NOTIFICATION_NONE);
1017 EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1019 #if defined(OS_CHROMEOS)
1020 // The press of VKEY_BROWSER_SEARCH should toggle the AppList
1021 EXPECT_TRUE(ProcessInController(ui::Accelerator(ui::VKEY_BROWSER_SEARCH,
1022 ui::EF_NONE)));
1023 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1024 EXPECT_FALSE(ProcessInController(ReleaseAccelerator(ui::VKEY_BROWSER_SEARCH,
1025 ui::EF_NONE)));
1026 EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1027 #endif
1030 TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) {
1031 // Test IME shortcuts.
1033 ui::Accelerator control_space_down(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
1034 control_space_down.set_type(ui::ET_KEY_PRESSED);
1035 ui::Accelerator control_space_up(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
1036 control_space_up.set_type(ui::ET_KEY_RELEASED);
1037 const ui::Accelerator convert(ui::VKEY_CONVERT, ui::EF_NONE);
1038 const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, ui::EF_NONE);
1039 const ui::Accelerator wide_half_1(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE);
1040 const ui::Accelerator wide_half_2(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE);
1041 const ui::Accelerator hangul(ui::VKEY_HANGUL, ui::EF_NONE);
1042 EXPECT_FALSE(ProcessInController(control_space_down));
1043 EXPECT_FALSE(ProcessInController(control_space_up));
1044 EXPECT_FALSE(ProcessInController(convert));
1045 EXPECT_FALSE(ProcessInController(non_convert));
1046 EXPECT_FALSE(ProcessInController(wide_half_1));
1047 EXPECT_FALSE(ProcessInController(wide_half_2));
1048 EXPECT_FALSE(ProcessInController(hangul));
1049 DummyImeControlDelegate* delegate = new DummyImeControlDelegate;
1050 GetController()->SetImeControlDelegate(
1051 scoped_ptr<ImeControlDelegate>(delegate).Pass());
1052 EXPECT_EQ(0, delegate->handle_previous_ime_count());
1053 EXPECT_TRUE(ProcessInController(control_space_down));
1054 EXPECT_EQ(1, delegate->handle_previous_ime_count());
1055 EXPECT_TRUE(ProcessInController(control_space_up));
1056 EXPECT_EQ(1, delegate->handle_previous_ime_count());
1057 EXPECT_EQ(0, delegate->handle_switch_ime_count());
1058 EXPECT_TRUE(ProcessInController(convert));
1059 EXPECT_EQ(1, delegate->handle_switch_ime_count());
1060 EXPECT_TRUE(ProcessInController(non_convert));
1061 EXPECT_EQ(2, delegate->handle_switch_ime_count());
1062 EXPECT_TRUE(ProcessInController(wide_half_1));
1063 EXPECT_EQ(3, delegate->handle_switch_ime_count());
1064 EXPECT_TRUE(ProcessInController(wide_half_2));
1065 EXPECT_EQ(4, delegate->handle_switch_ime_count());
1066 EXPECT_TRUE(ProcessInController(hangul));
1067 EXPECT_EQ(5, delegate->handle_switch_ime_count());
1070 // Test IME shortcuts that are triggered on key release.
1072 const ui::Accelerator shift_alt_press(ui::VKEY_MENU,
1073 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1074 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1075 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT,
1076 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1077 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1079 DummyImeControlDelegate* delegate = new DummyImeControlDelegate;
1080 GetController()->SetImeControlDelegate(
1081 scoped_ptr<ImeControlDelegate>(delegate).Pass());
1082 EXPECT_EQ(0, delegate->handle_next_ime_count());
1083 EXPECT_FALSE(ProcessInController(shift_alt_press));
1084 EXPECT_TRUE(ProcessInController(shift_alt));
1085 EXPECT_EQ(1, delegate->handle_next_ime_count());
1086 EXPECT_FALSE(ProcessInController(alt_shift_press));
1087 EXPECT_TRUE(ProcessInController(alt_shift));
1088 EXPECT_EQ(2, delegate->handle_next_ime_count());
1090 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1091 // released.
1092 const ui::Accelerator shift_alt_x_press(
1093 ui::VKEY_X,
1094 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1095 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
1096 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1098 EXPECT_FALSE(ProcessInController(shift_alt_press));
1099 EXPECT_FALSE(ProcessInController(shift_alt_x_press));
1100 EXPECT_FALSE(ProcessInController(shift_alt_x));
1101 EXPECT_FALSE(ProcessInController(shift_alt));
1102 EXPECT_EQ(2, delegate->handle_next_ime_count());
1104 // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
1105 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1106 const ui::Accelerator shift_alt_return_press(
1107 ui::VKEY_RETURN,
1108 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1109 const ReleaseAccelerator shift_alt_return(
1110 ui::VKEY_RETURN,
1111 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1113 EXPECT_FALSE(ProcessInController(shift_alt_press));
1114 EXPECT_FALSE(ProcessInController(shift_alt_return_press));
1115 EXPECT_FALSE(ProcessInController(shift_alt_return));
1116 EXPECT_TRUE(ProcessInController(shift_alt));
1117 EXPECT_EQ(3, delegate->handle_next_ime_count());
1119 const ui::Accelerator shift_alt_space_press(
1120 ui::VKEY_SPACE,
1121 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1122 const ReleaseAccelerator shift_alt_space(
1123 ui::VKEY_SPACE,
1124 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1126 EXPECT_FALSE(ProcessInController(shift_alt_press));
1127 EXPECT_FALSE(ProcessInController(shift_alt_space_press));
1128 EXPECT_FALSE(ProcessInController(shift_alt_space));
1129 EXPECT_TRUE(ProcessInController(shift_alt));
1130 EXPECT_EQ(4, delegate->handle_next_ime_count());
1133 #if defined(OS_CHROMEOS)
1134 // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
1136 const ui::Accelerator shift_alt_press(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1137 const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1138 const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1139 const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1141 DummyImeControlDelegate* delegate = new DummyImeControlDelegate;
1142 GetController()->SetImeControlDelegate(
1143 scoped_ptr<ImeControlDelegate>(delegate).Pass());
1144 EXPECT_EQ(0, delegate->handle_next_ime_count());
1145 EXPECT_FALSE(ProcessInController(shift_alt_press));
1146 EXPECT_TRUE(ProcessInController(shift_alt));
1147 EXPECT_EQ(1, delegate->handle_next_ime_count());
1148 EXPECT_FALSE(ProcessInController(alt_shift_press));
1149 EXPECT_TRUE(ProcessInController(alt_shift));
1150 EXPECT_EQ(2, delegate->handle_next_ime_count());
1152 // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1153 // released.
1154 const ui::Accelerator shift_alt_x_press(
1155 ui::VKEY_X,
1156 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1157 const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
1158 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1160 EXPECT_FALSE(ProcessInController(shift_alt_press));
1161 EXPECT_FALSE(ProcessInController(shift_alt_x_press));
1162 EXPECT_FALSE(ProcessInController(shift_alt_x));
1163 EXPECT_FALSE(ProcessInController(shift_alt));
1164 EXPECT_EQ(2, delegate->handle_next_ime_count());
1166 #endif
1169 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1170 TEST_F(AcceleratorControllerTest, ImeGlobalAcceleratorsWorkaround139556) {
1171 // The workaround for crbug.com/139556 depends on the fact that we don't
1172 // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1173 const ui::Accelerator shift_alt_return_press(
1174 ui::VKEY_RETURN,
1175 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1176 EXPECT_FALSE(ProcessInController(shift_alt_return_press));
1177 const ui::Accelerator shift_alt_space_press(
1178 ui::VKEY_SPACE,
1179 ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1180 EXPECT_FALSE(ProcessInController(shift_alt_space_press));
1183 TEST_F(AcceleratorControllerTest, PreferredReservedAccelerators) {
1184 #if defined(OS_CHROMEOS)
1185 // Power key is reserved on chromeos.
1186 EXPECT_TRUE(GetController()->IsReserved(
1187 ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE)));
1188 EXPECT_FALSE(GetController()->IsPreferred(
1189 ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE)));
1190 #endif
1191 // ALT+Tab are not reserved but preferred.
1192 EXPECT_FALSE(GetController()->IsReserved(
1193 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
1194 EXPECT_FALSE(GetController()->IsReserved(
1195 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
1196 EXPECT_TRUE(GetController()->IsPreferred(
1197 ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
1198 EXPECT_TRUE(GetController()->IsPreferred(
1199 ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
1201 // Others are not reserved nor preferred
1202 EXPECT_FALSE(GetController()->IsReserved(
1203 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1204 EXPECT_FALSE(GetController()->IsPreferred(
1205 ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1206 EXPECT_FALSE(GetController()->IsReserved(
1207 ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE)));
1208 EXPECT_FALSE(GetController()->IsPreferred(
1209 ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE)));
1210 EXPECT_FALSE(GetController()->IsReserved(
1211 ui::Accelerator(ui::VKEY_A, ui::EF_NONE)));
1212 EXPECT_FALSE(GetController()->IsPreferred(
1213 ui::Accelerator(ui::VKEY_A, ui::EF_NONE)));
1216 namespace {
1218 class PreferredReservedAcceleratorsTest : public test::AshTestBase {
1219 public:
1220 PreferredReservedAcceleratorsTest() {}
1221 ~PreferredReservedAcceleratorsTest() override {}
1223 // test::AshTestBase:
1224 void SetUp() override {
1225 AshTestBase::SetUp();
1226 Shell::GetInstance()->lock_state_controller()->
1227 set_animator_for_test(new test::TestSessionStateAnimator);
1230 private:
1231 DISALLOW_COPY_AND_ASSIGN(PreferredReservedAcceleratorsTest);
1234 } // namespace
1236 TEST_F(PreferredReservedAcceleratorsTest, AcceleratorsWithFullscreen) {
1237 aura::Window* w1 = CreateTestWindowInShellWithId(0);
1238 aura::Window* w2 = CreateTestWindowInShellWithId(1);
1239 wm::ActivateWindow(w1);
1241 wm::WMEvent fullscreen(wm::WM_EVENT_FULLSCREEN);
1242 wm::WindowState* w1_state = wm::GetWindowState(w1);
1243 w1_state->OnWMEvent(&fullscreen);
1244 ASSERT_TRUE(w1_state->IsFullscreen());
1246 ui::test::EventGenerator& generator = GetEventGenerator();
1247 #if defined(OS_CHROMEOS)
1248 // Power key (reserved) should always be handled.
1249 LockStateController::TestApi test_api(
1250 Shell::GetInstance()->lock_state_controller());
1251 EXPECT_FALSE(test_api.is_animating_lock());
1252 generator.PressKey(ui::VKEY_POWER, ui::EF_NONE);
1253 EXPECT_TRUE(test_api.is_animating_lock());
1254 #endif
1256 // A fullscreen window can consume ALT-TAB (preferred).
1257 ASSERT_EQ(w1, wm::GetActiveWindow());
1258 generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN);
1259 ASSERT_EQ(w1, wm::GetActiveWindow());
1260 ASSERT_NE(w2, wm::GetActiveWindow());
1262 // ALT-TAB is non repeatable. Press A to cancel the
1263 // repeat record.
1264 generator.PressKey(ui::VKEY_A, ui::EF_NONE);
1265 generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE);
1267 // A normal window shouldn't consume preferred accelerator.
1268 wm::WMEvent normal(wm::WM_EVENT_NORMAL);
1269 w1_state->OnWMEvent(&normal);
1270 ASSERT_FALSE(w1_state->IsFullscreen());
1272 EXPECT_EQ(w1, wm::GetActiveWindow());
1273 generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN);
1274 ASSERT_NE(w1, wm::GetActiveWindow());
1275 ASSERT_EQ(w2, wm::GetActiveWindow());
1278 #if defined(OS_CHROMEOS)
1279 TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) {
1280 std::set<AcceleratorAction> all_actions;
1281 for (size_t i = 0 ; i < kAcceleratorDataLength; ++i)
1282 all_actions.insert(kAcceleratorData[i].action);
1283 std::set<AcceleratorAction> all_debug_actions;
1284 for (size_t i = 0 ; i < kDebugAcceleratorDataLength; ++i)
1285 all_debug_actions.insert(kDebugAcceleratorData[i].action);
1287 std::set<AcceleratorAction> actionsAllowedAtModalWindow;
1288 for (size_t k = 0 ; k < kActionsAllowedAtModalWindowLength; ++k)
1289 actionsAllowedAtModalWindow.insert(kActionsAllowedAtModalWindow[k]);
1290 for (std::set<AcceleratorAction>::const_iterator it =
1291 actionsAllowedAtModalWindow.begin();
1292 it != actionsAllowedAtModalWindow.end(); ++it) {
1293 EXPECT_TRUE(all_actions.find(*it) != all_actions.end() ||
1294 all_debug_actions.find(*it) != all_debug_actions.end())
1295 << " action from kActionsAllowedAtModalWindow"
1296 << " not found in kAcceleratorData or kDebugAcceleratorData. "
1297 << "action: " << *it;
1299 scoped_ptr<aura::Window> window(
1300 CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1301 wm::ActivateWindow(window.get());
1302 Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1303 for (std::set<AcceleratorAction>::const_iterator it = all_actions.begin();
1304 it != all_actions.end(); ++it) {
1305 if (actionsAllowedAtModalWindow.find(*it) ==
1306 actionsAllowedAtModalWindow.end()) {
1307 EXPECT_TRUE(GetController()->PerformActionIfEnabled(*it))
1308 << " for action (disallowed at modal window): " << *it;
1311 // Testing of top row (F5-F10) accelerators that should still work
1312 // when a modal window is open
1314 // Screenshot
1316 test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
1317 delegate->set_can_take_screenshot(false);
1318 EXPECT_TRUE(ProcessInController(
1319 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1320 EXPECT_TRUE(
1321 ProcessInController(ui::Accelerator(
1322 ui::VKEY_PRINT, ui::EF_NONE)));
1323 EXPECT_TRUE(ProcessInController(ui::Accelerator(
1324 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1325 delegate->set_can_take_screenshot(true);
1326 EXPECT_EQ(0, delegate->handle_take_screenshot_count());
1327 EXPECT_TRUE(ProcessInController(
1328 ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1329 EXPECT_EQ(1, delegate->handle_take_screenshot_count());
1330 EXPECT_TRUE(
1331 ProcessInController(ui::Accelerator(
1332 ui::VKEY_PRINT, ui::EF_NONE)));
1333 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1334 EXPECT_TRUE(ProcessInController(ui::Accelerator(
1335 ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1336 EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1338 // Brightness
1339 const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
1340 const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
1342 DummyBrightnessControlDelegate* delegate =
1343 new DummyBrightnessControlDelegate;
1344 GetController()->SetBrightnessControlDelegate(
1345 scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1346 EXPECT_EQ(0, delegate->handle_brightness_down_count());
1347 EXPECT_TRUE(ProcessInController(brightness_down));
1348 EXPECT_EQ(1, delegate->handle_brightness_down_count());
1349 EXPECT_EQ(brightness_down, delegate->last_accelerator());
1350 EXPECT_EQ(0, delegate->handle_brightness_up_count());
1351 EXPECT_TRUE(ProcessInController(brightness_up));
1352 EXPECT_EQ(1, delegate->handle_brightness_up_count());
1353 EXPECT_EQ(brightness_up, delegate->last_accelerator());
1355 // Volume
1356 const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
1357 const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
1358 const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
1360 EXPECT_TRUE(ProcessInController(volume_mute));
1361 EXPECT_TRUE(ProcessInController(volume_down));
1362 EXPECT_TRUE(ProcessInController(volume_up));
1363 TestVolumeControlDelegate* delegate = new TestVolumeControlDelegate;
1364 ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1365 scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1366 EXPECT_EQ(0, delegate->handle_volume_mute_count());
1367 EXPECT_TRUE(ProcessInController(volume_mute));
1368 EXPECT_EQ(1, delegate->handle_volume_mute_count());
1369 EXPECT_EQ(volume_mute, delegate->last_accelerator());
1370 EXPECT_EQ(0, delegate->handle_volume_down_count());
1371 EXPECT_TRUE(ProcessInController(volume_down));
1372 EXPECT_EQ(1, delegate->handle_volume_down_count());
1373 EXPECT_EQ(volume_down, delegate->last_accelerator());
1374 EXPECT_EQ(0, delegate->handle_volume_up_count());
1375 EXPECT_TRUE(ProcessInController(volume_up));
1376 EXPECT_EQ(1, delegate->handle_volume_up_count());
1377 EXPECT_EQ(volume_up, delegate->last_accelerator());
1380 #endif
1382 TEST_F(AcceleratorControllerTest, DisallowedWithNoWindow) {
1383 AccessibilityDelegate* delegate =
1384 ash::Shell::GetInstance()->accessibility_delegate();
1386 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1387 delegate->TriggerAccessibilityAlert(ui::A11Y_ALERT_NONE);
1388 EXPECT_TRUE(
1389 GetController()->PerformActionIfEnabled(kActionsNeedingWindow[i]));
1390 EXPECT_EQ(delegate->GetLastAccessibilityAlert(),
1391 ui::A11Y_ALERT_WINDOW_NEEDED);
1394 // Make sure we don't alert if we do have a window.
1395 scoped_ptr<aura::Window> window;
1396 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1397 window.reset(CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1398 wm::ActivateWindow(window.get());
1399 delegate->TriggerAccessibilityAlert(ui::A11Y_ALERT_NONE);
1400 GetController()->PerformActionIfEnabled(kActionsNeedingWindow[i]);
1401 EXPECT_NE(delegate->GetLastAccessibilityAlert(),
1402 ui::A11Y_ALERT_WINDOW_NEEDED);
1405 // Don't alert if we have a minimized window either.
1406 for (size_t i = 0; i < kActionsNeedingWindowLength; ++i) {
1407 window.reset(CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1408 wm::ActivateWindow(window.get());
1409 GetController()->PerformActionIfEnabled(WINDOW_MINIMIZE);
1410 delegate->TriggerAccessibilityAlert(ui::A11Y_ALERT_NONE);
1411 GetController()->PerformActionIfEnabled(kActionsNeedingWindow[i]);
1412 EXPECT_NE(delegate->GetLastAccessibilityAlert(),
1413 ui::A11Y_ALERT_WINDOW_NEEDED);
1417 } // namespace ash