- add sources.
[platform/framework/web/crosswalk.git] / src / ash / accelerators / accelerator_controller_unittest.cc
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.
4
5 #include "ash/accelerators/accelerator_controller.h"
6 #include "ash/accelerators/accelerator_table.h"
7 #include "ash/accessibility_delegate.h"
8 #include "ash/caps_lock_delegate.h"
9 #include "ash/display/display_manager.h"
10 #include "ash/ime_control_delegate.h"
11 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h"
13 #include "ash/system/brightness_control_delegate.h"
14 #include "ash/system/keyboard_brightness/keyboard_brightness_control_delegate.h"
15 #include "ash/system/tray/system_tray_delegate.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/test/display_manager_test_api.h"
18 #include "ash/test/test_screenshot_delegate.h"
19 #include "ash/test/test_shell_delegate.h"
20 #include "ash/volume_control_delegate.h"
21 #include "ash/wm/window_state.h"
22 #include "ash/wm/window_util.h"
23 #include "ui/aura/root_window.h"
24 #include "ui/aura/test/test_window_delegate.h"
25 #include "ui/aura/test/test_windows.h"
26 #include "ui/aura/window.h"
27 #include "ui/events/event.h"
28
29 #if defined(USE_X11)
30 #include <X11/Xlib.h>
31 #include "ui/events/x/events_x_utils.h"
32 #endif
33
34 namespace ash {
35
36 namespace {
37
38 class TestTarget : public ui::AcceleratorTarget {
39  public:
40   TestTarget() : accelerator_pressed_count_(0) {}
41   virtual ~TestTarget() {}
42
43   int accelerator_pressed_count() const {
44     return accelerator_pressed_count_;
45   }
46
47   void set_accelerator_pressed_count(int accelerator_pressed_count) {
48     accelerator_pressed_count_ = accelerator_pressed_count;
49   }
50
51   // Overridden from ui::AcceleratorTarget:
52   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
53   virtual bool CanHandleAccelerators() const OVERRIDE;
54
55  private:
56   int accelerator_pressed_count_;
57
58   DISALLOW_COPY_AND_ASSIGN(TestTarget);
59 };
60
61 class ReleaseAccelerator : public ui::Accelerator {
62  public:
63   ReleaseAccelerator(ui::KeyboardCode keycode, int modifiers)
64       : ui::Accelerator(keycode, modifiers) {
65     set_type(ui::ET_KEY_RELEASED);
66   }
67 };
68
69 class DummyVolumeControlDelegate : public VolumeControlDelegate {
70  public:
71   explicit DummyVolumeControlDelegate(bool consume)
72       : consume_(consume),
73         handle_volume_mute_count_(0),
74         handle_volume_down_count_(0),
75         handle_volume_up_count_(0) {
76   }
77   virtual ~DummyVolumeControlDelegate() {}
78
79   virtual bool HandleVolumeMute(const ui::Accelerator& accelerator) OVERRIDE {
80     ++handle_volume_mute_count_;
81     last_accelerator_ = accelerator;
82     return consume_;
83   }
84   virtual bool HandleVolumeDown(const ui::Accelerator& accelerator) OVERRIDE {
85     ++handle_volume_down_count_;
86     last_accelerator_ = accelerator;
87     return consume_;
88   }
89   virtual bool HandleVolumeUp(const ui::Accelerator& accelerator) OVERRIDE {
90     ++handle_volume_up_count_;
91     last_accelerator_ = accelerator;
92     return consume_;
93   }
94
95   int handle_volume_mute_count() const {
96     return handle_volume_mute_count_;
97   }
98   int handle_volume_down_count() const {
99     return handle_volume_down_count_;
100   }
101   int handle_volume_up_count() const {
102     return handle_volume_up_count_;
103   }
104   const ui::Accelerator& last_accelerator() const {
105     return last_accelerator_;
106   }
107
108  private:
109   const bool consume_;
110   int handle_volume_mute_count_;
111   int handle_volume_down_count_;
112   int handle_volume_up_count_;
113   ui::Accelerator last_accelerator_;
114
115   DISALLOW_COPY_AND_ASSIGN(DummyVolumeControlDelegate);
116 };
117
118 class DummyBrightnessControlDelegate : public BrightnessControlDelegate {
119  public:
120   explicit DummyBrightnessControlDelegate(bool consume)
121       : consume_(consume),
122         handle_brightness_down_count_(0),
123         handle_brightness_up_count_(0) {
124   }
125   virtual ~DummyBrightnessControlDelegate() {}
126
127   virtual bool HandleBrightnessDown(
128       const ui::Accelerator& accelerator) OVERRIDE {
129     ++handle_brightness_down_count_;
130     last_accelerator_ = accelerator;
131     return consume_;
132   }
133   virtual bool HandleBrightnessUp(const ui::Accelerator& accelerator) OVERRIDE {
134     ++handle_brightness_up_count_;
135     last_accelerator_ = accelerator;
136     return consume_;
137   }
138   virtual void SetBrightnessPercent(double percent, bool gradual) OVERRIDE {}
139   virtual void GetBrightnessPercent(
140       const base::Callback<void(double)>& callback) OVERRIDE {
141     callback.Run(100.0);
142   }
143
144   int handle_brightness_down_count() const {
145     return handle_brightness_down_count_;
146   }
147   int handle_brightness_up_count() const {
148     return handle_brightness_up_count_;
149   }
150   const ui::Accelerator& last_accelerator() const {
151     return last_accelerator_;
152   }
153
154  private:
155   const bool consume_;
156   int handle_brightness_down_count_;
157   int handle_brightness_up_count_;
158   ui::Accelerator last_accelerator_;
159
160   DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate);
161 };
162
163 class DummyImeControlDelegate : public ImeControlDelegate {
164  public:
165   explicit DummyImeControlDelegate(bool consume)
166       : consume_(consume),
167         handle_next_ime_count_(0),
168         handle_previous_ime_count_(0),
169         handle_switch_ime_count_(0) {
170   }
171   virtual ~DummyImeControlDelegate() {}
172
173   virtual bool HandleNextIme() OVERRIDE {
174     ++handle_next_ime_count_;
175     return consume_;
176   }
177   virtual bool HandlePreviousIme(const ui::Accelerator& accelerator) OVERRIDE {
178     ++handle_previous_ime_count_;
179     last_accelerator_ = accelerator;
180     return consume_;
181   }
182   virtual bool HandleSwitchIme(const ui::Accelerator& accelerator) OVERRIDE {
183     ++handle_switch_ime_count_;
184     last_accelerator_ = accelerator;
185     return consume_;
186   }
187
188   int handle_next_ime_count() const {
189     return handle_next_ime_count_;
190   }
191   int handle_previous_ime_count() const {
192     return handle_previous_ime_count_;
193   }
194   int handle_switch_ime_count() const {
195     return handle_switch_ime_count_;
196   }
197   const ui::Accelerator& last_accelerator() const {
198     return last_accelerator_;
199   }
200   virtual ui::Accelerator RemapAccelerator(
201       const ui::Accelerator& accelerator) OVERRIDE {
202     return ui::Accelerator(accelerator);
203   }
204
205  private:
206   const bool consume_;
207   int handle_next_ime_count_;
208   int handle_previous_ime_count_;
209   int handle_switch_ime_count_;
210   ui::Accelerator last_accelerator_;
211
212   DISALLOW_COPY_AND_ASSIGN(DummyImeControlDelegate);
213 };
214
215 class DummyKeyboardBrightnessControlDelegate
216     : public KeyboardBrightnessControlDelegate {
217  public:
218   explicit DummyKeyboardBrightnessControlDelegate(bool consume)
219       : consume_(consume),
220         handle_keyboard_brightness_down_count_(0),
221         handle_keyboard_brightness_up_count_(0) {
222   }
223   virtual ~DummyKeyboardBrightnessControlDelegate() {}
224
225   virtual bool HandleKeyboardBrightnessDown(
226       const ui::Accelerator& accelerator) OVERRIDE {
227     ++handle_keyboard_brightness_down_count_;
228     last_accelerator_ = accelerator;
229     return consume_;
230   }
231
232   virtual bool HandleKeyboardBrightnessUp(
233       const ui::Accelerator& accelerator) OVERRIDE {
234     ++handle_keyboard_brightness_up_count_;
235     last_accelerator_ = accelerator;
236     return consume_;
237   }
238
239   int handle_keyboard_brightness_down_count() const {
240     return handle_keyboard_brightness_down_count_;
241   }
242
243   int handle_keyboard_brightness_up_count() const {
244     return handle_keyboard_brightness_up_count_;
245   }
246
247   const ui::Accelerator& last_accelerator() const {
248     return last_accelerator_;
249   }
250
251  private:
252   const bool consume_;
253   int handle_keyboard_brightness_down_count_;
254   int handle_keyboard_brightness_up_count_;
255   ui::Accelerator last_accelerator_;
256
257   DISALLOW_COPY_AND_ASSIGN(DummyKeyboardBrightnessControlDelegate);
258 };
259
260 bool TestTarget::AcceleratorPressed(const ui::Accelerator& accelerator) {
261   ++accelerator_pressed_count_;
262   return true;
263 }
264
265 bool TestTarget::CanHandleAccelerators() const {
266   return true;
267 }
268
269 }  // namespace
270
271 class AcceleratorControllerTest : public test::AshTestBase {
272  public:
273   AcceleratorControllerTest() {}
274   virtual ~AcceleratorControllerTest() {}
275
276  protected:
277   void EnableInternalDisplay() {
278     test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
279         SetFirstDisplayAsInternalDisplay();
280   }
281
282   static AcceleratorController* GetController();
283   static bool ProcessWithContext(const ui::Accelerator& accelerator);
284
285   // Several functions to access ExitWarningHandler (as friend).
286   static void StubForTest(ExitWarningHandler* ewh) {
287     ewh->stub_timer_for_test_ = true;
288   }
289   static void Reset(ExitWarningHandler* ewh) {
290     ewh->state_ = ExitWarningHandler::IDLE;
291   }
292   static void SimulateTimerExpired(ExitWarningHandler* ewh) {
293     ewh->TimerAction();
294   }
295   static bool is_ui_shown(ExitWarningHandler* ewh) {
296     return !!ewh->widget_;
297   }
298   static bool is_idle(ExitWarningHandler* ewh) {
299     return ewh->state_ == ExitWarningHandler::IDLE;
300   }
301   static bool is_exiting(ExitWarningHandler* ewh) {
302     return ewh->state_ == ExitWarningHandler::EXITING;
303   }
304
305  private:
306   DISALLOW_COPY_AND_ASSIGN(AcceleratorControllerTest);
307 };
308
309 AcceleratorController* AcceleratorControllerTest::GetController() {
310   return Shell::GetInstance()->accelerator_controller();
311 }
312
313 bool AcceleratorControllerTest::ProcessWithContext(
314     const ui::Accelerator& accelerator) {
315   AcceleratorController* controller = GetController();
316   controller->context()->UpdateContext(accelerator);
317   return controller->Process(accelerator);
318 }
319
320 #if !defined(OS_WIN)
321 // Double press of exit shortcut => exiting
322 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestDoublePress) {
323   ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
324   ui::Accelerator release(press);
325   release.set_type(ui::ET_KEY_RELEASED);
326   ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
327   ASSERT_TRUE(!!ewh);
328   StubForTest(ewh);
329   EXPECT_TRUE(is_idle(ewh));
330   EXPECT_FALSE(is_ui_shown(ewh));
331   EXPECT_TRUE(ProcessWithContext(press));
332   EXPECT_FALSE(ProcessWithContext(release));
333   EXPECT_FALSE(is_idle(ewh));
334   EXPECT_TRUE(is_ui_shown(ewh));
335   EXPECT_TRUE(ProcessWithContext(press));  // second press before timer.
336   EXPECT_FALSE(ProcessWithContext(release));
337   SimulateTimerExpired(ewh);
338   EXPECT_TRUE(is_exiting(ewh));
339   EXPECT_FALSE(is_ui_shown(ewh));
340   Reset(ewh);
341 }
342
343 // Single press of exit shortcut before timer => idle
344 TEST_F(AcceleratorControllerTest, ExitWarningHandlerTestSinglePress) {
345   ui::Accelerator press(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
346   ui::Accelerator release(press);
347   release.set_type(ui::ET_KEY_RELEASED);
348   ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
349   ASSERT_TRUE(!!ewh);
350   StubForTest(ewh);
351   EXPECT_TRUE(is_idle(ewh));
352   EXPECT_FALSE(is_ui_shown(ewh));
353   EXPECT_TRUE(ProcessWithContext(press));
354   EXPECT_FALSE(ProcessWithContext(release));
355   EXPECT_FALSE(is_idle(ewh));
356   EXPECT_TRUE(is_ui_shown(ewh));
357   SimulateTimerExpired(ewh);
358   EXPECT_TRUE(is_idle(ewh));
359   EXPECT_FALSE(is_ui_shown(ewh));
360   Reset(ewh);
361 }
362
363 // Shutdown ash with exit warning bubble open should not crash.
364 TEST_F(AcceleratorControllerTest, LingeringExitWarningBubble) {
365   ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
366   ASSERT_TRUE(!!ewh);
367   StubForTest(ewh);
368
369   // Trigger once to show the bubble.
370   ewh->HandleAccelerator();
371   EXPECT_FALSE(is_idle(ewh));
372   EXPECT_TRUE(is_ui_shown(ewh));
373
374   // Exit ash and there should be no crash
375 }
376 #endif  // !defined(OS_WIN)
377
378 TEST_F(AcceleratorControllerTest, Register) {
379   const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
380   TestTarget target;
381   GetController()->Register(accelerator_a, &target);
382
383   // The registered accelerator is processed.
384   EXPECT_TRUE(ProcessWithContext(accelerator_a));
385   EXPECT_EQ(1, target.accelerator_pressed_count());
386 }
387
388 TEST_F(AcceleratorControllerTest, RegisterMultipleTarget) {
389   const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
390   TestTarget target1;
391   GetController()->Register(accelerator_a, &target1);
392   TestTarget target2;
393   GetController()->Register(accelerator_a, &target2);
394
395   // If multiple targets are registered with the same accelerator, the target
396   // registered later processes the accelerator.
397   EXPECT_TRUE(ProcessWithContext(accelerator_a));
398   EXPECT_EQ(0, target1.accelerator_pressed_count());
399   EXPECT_EQ(1, target2.accelerator_pressed_count());
400 }
401
402 TEST_F(AcceleratorControllerTest, Unregister) {
403   const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
404   TestTarget target;
405   GetController()->Register(accelerator_a, &target);
406   const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
407   GetController()->Register(accelerator_b, &target);
408
409   // Unregistering a different accelerator does not affect the other
410   // accelerator.
411   GetController()->Unregister(accelerator_b, &target);
412   EXPECT_TRUE(ProcessWithContext(accelerator_a));
413   EXPECT_EQ(1, target.accelerator_pressed_count());
414
415   // The unregistered accelerator is no longer processed.
416   target.set_accelerator_pressed_count(0);
417   GetController()->Unregister(accelerator_a, &target);
418   EXPECT_FALSE(ProcessWithContext(accelerator_a));
419   EXPECT_EQ(0, target.accelerator_pressed_count());
420 }
421
422 TEST_F(AcceleratorControllerTest, UnregisterAll) {
423   const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
424   TestTarget target1;
425   GetController()->Register(accelerator_a, &target1);
426   const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
427   GetController()->Register(accelerator_b, &target1);
428   const ui::Accelerator accelerator_c(ui::VKEY_C, ui::EF_NONE);
429   TestTarget target2;
430   GetController()->Register(accelerator_c, &target2);
431   GetController()->UnregisterAll(&target1);
432
433   // All the accelerators registered for |target1| are no longer processed.
434   EXPECT_FALSE(ProcessWithContext(accelerator_a));
435   EXPECT_FALSE(ProcessWithContext(accelerator_b));
436   EXPECT_EQ(0, target1.accelerator_pressed_count());
437
438   // UnregisterAll with a different target does not affect the other target.
439   EXPECT_TRUE(ProcessWithContext(accelerator_c));
440   EXPECT_EQ(1, target2.accelerator_pressed_count());
441 }
442
443 TEST_F(AcceleratorControllerTest, Process) {
444   const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
445   TestTarget target1;
446   GetController()->Register(accelerator_a, &target1);
447
448   // The registered accelerator is processed.
449   EXPECT_TRUE(ProcessWithContext(accelerator_a));
450   EXPECT_EQ(1, target1.accelerator_pressed_count());
451
452   // The non-registered accelerator is not processed.
453   const ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
454   EXPECT_FALSE(ProcessWithContext(accelerator_b));
455 }
456
457 TEST_F(AcceleratorControllerTest, IsRegistered) {
458   const ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
459   const ui::Accelerator accelerator_shift_a(ui::VKEY_A, ui::EF_SHIFT_DOWN);
460   TestTarget target;
461   GetController()->Register(accelerator_a, &target);
462   EXPECT_TRUE(GetController()->IsRegistered(accelerator_a));
463   EXPECT_FALSE(GetController()->IsRegistered(accelerator_shift_a));
464   GetController()->UnregisterAll(&target);
465   EXPECT_FALSE(GetController()->IsRegistered(accelerator_a));
466 }
467
468 TEST_F(AcceleratorControllerTest, WindowSnap) {
469   scoped_ptr<aura::Window> window(
470       CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
471   const ui::Accelerator dummy;
472
473   wm::WindowState* window_state = wm::GetWindowState(window.get());
474
475   window_state->Activate();
476
477   {
478     GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
479     gfx::Rect snap_left = window->bounds();
480     GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
481     EXPECT_NE(window->bounds().ToString(), snap_left.ToString());
482     GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
483     EXPECT_NE(window->bounds().ToString(), snap_left.ToString());
484
485     // It should cycle back to the first snapped position.
486     GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
487     EXPECT_EQ(window->bounds().ToString(), snap_left.ToString());
488   }
489   {
490     GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
491     gfx::Rect snap_right = window->bounds();
492     GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
493     EXPECT_NE(window->bounds().ToString(), snap_right.ToString());
494     GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
495     EXPECT_NE(window->bounds().ToString(), snap_right.ToString());
496
497     // It should cycle back to the first snapped position.
498     GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
499     EXPECT_EQ(window->bounds().ToString(), snap_right.ToString());
500   }
501   {
502     gfx::Rect normal_bounds = window->bounds();
503
504     GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
505     EXPECT_TRUE(window_state->IsMaximized());
506     EXPECT_NE(normal_bounds.ToString(), window->bounds().ToString());
507
508     GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
509     EXPECT_FALSE(window_state->IsMaximized());
510     EXPECT_EQ(normal_bounds.ToString(), window->bounds().ToString());
511
512     GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
513     GetController()->PerformAction(WINDOW_SNAP_LEFT, dummy);
514     EXPECT_FALSE(window_state->IsMaximized());
515
516     GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
517     GetController()->PerformAction(WINDOW_SNAP_RIGHT, dummy);
518     EXPECT_FALSE(window_state->IsMaximized());
519
520     GetController()->PerformAction(TOGGLE_MAXIMIZED, dummy);
521     EXPECT_TRUE(window_state->IsMaximized());
522     GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
523     EXPECT_FALSE(window_state->IsMaximized());
524     EXPECT_TRUE(window_state->IsMinimized());
525     window_state->Restore();
526     window_state->Activate();
527   }
528   {
529     GetController()->PerformAction(WINDOW_MINIMIZE, dummy);
530     EXPECT_TRUE(window_state->IsMinimized());
531   }
532 }
533
534 #if defined(OS_WIN) && defined(USE_AURA)
535 // Bug 297650.
536 #define MAYBE_ControllerContext DISABLED_ControllerContext
537 #else
538 #define MAYBE_ControllerContext ControllerContext
539 #endif
540
541 TEST_F(AcceleratorControllerTest, MAYBE_ControllerContext) {
542   ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
543   ui::Accelerator accelerator_a2(ui::VKEY_A, ui::EF_NONE);
544   ui::Accelerator accelerator_b(ui::VKEY_B, ui::EF_NONE);
545
546   accelerator_a.set_type(ui::ET_KEY_PRESSED);
547   accelerator_a2.set_type(ui::ET_KEY_RELEASED);
548   accelerator_b.set_type(ui::ET_KEY_PRESSED);
549
550   EXPECT_FALSE(GetController()->context()->repeated());
551   EXPECT_EQ(ui::ET_UNKNOWN,
552             GetController()->context()->previous_accelerator().type());
553
554   GetController()->context()->UpdateContext(accelerator_a);
555   EXPECT_FALSE(GetController()->context()->repeated());
556   EXPECT_EQ(ui::ET_UNKNOWN,
557             GetController()->context()->previous_accelerator().type());
558
559   GetController()->context()->UpdateContext(accelerator_a2);
560   EXPECT_FALSE(GetController()->context()->repeated());
561   EXPECT_EQ(ui::ET_KEY_PRESSED,
562             GetController()->context()->previous_accelerator().type());
563
564   GetController()->context()->UpdateContext(accelerator_a2);
565   EXPECT_TRUE(GetController()->context()->repeated());
566   EXPECT_EQ(ui::ET_KEY_RELEASED,
567             GetController()->context()->previous_accelerator().type());
568
569   GetController()->context()->UpdateContext(accelerator_b);
570   EXPECT_FALSE(GetController()->context()->repeated());
571   EXPECT_EQ(ui::ET_KEY_RELEASED,
572             GetController()->context()->previous_accelerator().type());
573 }
574
575 #if defined(OS_WIN) && defined(USE_AURA)
576 // crbug.com/314674
577 #define MAYBE_SuppressToggleMaximized DISABLED_SuppressToggleMaximized
578 #else
579 #define MAYBE_SuppressToggleMaximized SuppressToggleMaximized
580 #endif
581
582 TEST_F(AcceleratorControllerTest, MAYBE_SuppressToggleMaximized) {
583   scoped_ptr<aura::Window> window(
584       CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
585   wm::ActivateWindow(window.get());
586   const ui::Accelerator accelerator(ui::VKEY_A, ui::EF_NONE);
587   const ui::Accelerator empty_accelerator;
588
589   wm::WindowState* window_state = wm::GetWindowState(window.get());
590
591   // Toggling not suppressed.
592   GetController()->context()->UpdateContext(accelerator);
593   GetController()->PerformAction(TOGGLE_MAXIMIZED, accelerator);
594   EXPECT_TRUE(window_state->IsMaximized());
595
596   // The same accelerator - toggling suppressed.
597   GetController()->context()->UpdateContext(accelerator);
598   GetController()->PerformAction(TOGGLE_MAXIMIZED, accelerator);
599   EXPECT_TRUE(window_state->IsMaximized());
600
601   // Suppressed but not for gesture events.
602   GetController()->PerformAction(TOGGLE_MAXIMIZED, empty_accelerator);
603   EXPECT_FALSE(window_state->IsMaximized());
604 }
605
606 #if defined(OS_WIN) || defined(USE_X11)
607 TEST_F(AcceleratorControllerTest, ProcessOnce) {
608   ui::Accelerator accelerator_a(ui::VKEY_A, ui::EF_NONE);
609   TestTarget target;
610   GetController()->Register(accelerator_a, &target);
611
612   // The accelerator is processed only once.
613   aura::WindowEventDispatcher* dispatcher =
614       Shell::GetPrimaryRootWindow()->GetDispatcher();
615 #if defined(OS_WIN)
616   MSG msg1 = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 };
617   ui::TranslatedKeyEvent key_event1(msg1, false);
618   EXPECT_TRUE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
619       &key_event1));
620
621   MSG msg2 = { NULL, WM_CHAR, L'A', 0 };
622   ui::TranslatedKeyEvent key_event2(msg2, true);
623   EXPECT_FALSE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
624       &key_event2));
625
626   MSG msg3 = { NULL, WM_KEYUP, ui::VKEY_A, 0 };
627   ui::TranslatedKeyEvent key_event3(msg3, false);
628   EXPECT_FALSE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
629       &key_event3));
630 #elif defined(USE_X11)
631   XEvent key_event;
632   ui::InitXKeyEventForTesting(ui::ET_KEY_PRESSED,
633                               ui::VKEY_A,
634                               0,
635                               &key_event);
636   ui::TranslatedKeyEvent key_event1(&key_event, false);
637   EXPECT_TRUE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
638       &key_event1));
639
640   ui::TranslatedKeyEvent key_event2(&key_event, true);
641   EXPECT_FALSE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
642       &key_event2));
643
644   ui::InitXKeyEventForTesting(ui::ET_KEY_RELEASED,
645                               ui::VKEY_A,
646                               0,
647                               &key_event);
648   ui::TranslatedKeyEvent key_event3(&key_event, false);
649   EXPECT_FALSE(dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(
650       &key_event3));
651 #endif
652   EXPECT_EQ(1, target.accelerator_pressed_count());
653 }
654 #endif
655
656 TEST_F(AcceleratorControllerTest, GlobalAccelerators) {
657   // CycleBackward
658   EXPECT_TRUE(ProcessWithContext(
659       ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
660   // CycleForward
661   EXPECT_TRUE(ProcessWithContext(
662       ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
663   // CycleLinear
664   EXPECT_TRUE(ProcessWithContext(
665       ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE)));
666
667 #if defined(OS_CHROMEOS)
668   // Take screenshot / partial screenshot
669   // True should always be returned regardless of the existence of the delegate.
670   {
671     test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
672     delegate->set_can_take_screenshot(false);
673     EXPECT_TRUE(ProcessWithContext(
674         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
675     EXPECT_TRUE(ProcessWithContext(
676         ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
677     EXPECT_TRUE(ProcessWithContext(
678         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
679                         ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
680
681     delegate->set_can_take_screenshot(true);
682     EXPECT_EQ(0, delegate->handle_take_screenshot_count());
683     EXPECT_TRUE(ProcessWithContext(
684         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
685     EXPECT_EQ(1, delegate->handle_take_screenshot_count());
686     EXPECT_TRUE(ProcessWithContext(
687         ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
688     EXPECT_EQ(2, delegate->handle_take_screenshot_count());
689     EXPECT_TRUE(ProcessWithContext(
690         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
691                         ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
692     EXPECT_EQ(2, delegate->handle_take_screenshot_count());
693   }
694 #endif
695   // DisableCapsLock
696   {
697     CapsLockDelegate* delegate = Shell::GetInstance()->caps_lock_delegate();
698     delegate->SetCapsLockEnabled(true);
699     EXPECT_TRUE(delegate->IsCapsLockEnabled());
700     // Handled only on key release.
701     EXPECT_FALSE(ProcessWithContext(
702         ui::Accelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
703     EXPECT_TRUE(delegate->IsCapsLockEnabled());
704     EXPECT_TRUE(ProcessWithContext(
705         ReleaseAccelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
706     EXPECT_FALSE(delegate->IsCapsLockEnabled());
707     delegate->SetCapsLockEnabled(true);
708     EXPECT_FALSE(ProcessWithContext(
709         ui::Accelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
710     EXPECT_TRUE(delegate->IsCapsLockEnabled());
711     EXPECT_TRUE(ProcessWithContext(
712         ReleaseAccelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
713     EXPECT_FALSE(delegate->IsCapsLockEnabled());
714     delegate->SetCapsLockEnabled(true);
715     EXPECT_FALSE(ProcessWithContext(
716         ui::Accelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
717     EXPECT_TRUE(delegate->IsCapsLockEnabled());
718     EXPECT_TRUE(ProcessWithContext(
719         ReleaseAccelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
720     EXPECT_FALSE(delegate->IsCapsLockEnabled());
721
722     // Do not handle when a shift pressed with other keys.
723     delegate->SetCapsLockEnabled(true);
724     EXPECT_FALSE(ProcessWithContext(
725         ui::Accelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
726     EXPECT_TRUE(delegate->IsCapsLockEnabled());
727     EXPECT_FALSE(ProcessWithContext(
728         ReleaseAccelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
729     EXPECT_TRUE(delegate->IsCapsLockEnabled());
730
731     // Do not handle when a shift pressed with other keys, and shift is
732     // released first.
733     delegate->SetCapsLockEnabled(true);
734     EXPECT_FALSE(ProcessWithContext(
735         ui::Accelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
736     EXPECT_TRUE(delegate->IsCapsLockEnabled());
737     EXPECT_FALSE(ProcessWithContext(
738         ReleaseAccelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
739     EXPECT_TRUE(delegate->IsCapsLockEnabled());
740
741     EXPECT_FALSE(ProcessWithContext(
742         ui::Accelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
743     EXPECT_TRUE(delegate->IsCapsLockEnabled());
744     EXPECT_FALSE(ProcessWithContext(
745         ReleaseAccelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
746     EXPECT_TRUE(delegate->IsCapsLockEnabled());
747
748     EXPECT_FALSE(ProcessWithContext(
749         ui::Accelerator(ui::VKEY_A, ui::EF_SHIFT_DOWN)));
750     EXPECT_TRUE(delegate->IsCapsLockEnabled());
751     EXPECT_FALSE(ProcessWithContext(
752         ReleaseAccelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
753     EXPECT_TRUE(delegate->IsCapsLockEnabled());
754
755     // Do not consume shift keyup when caps lock is off.
756     delegate->SetCapsLockEnabled(false);
757     EXPECT_FALSE(ProcessWithContext(
758         ui::Accelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
759     EXPECT_FALSE(ProcessWithContext(
760         ReleaseAccelerator(ui::VKEY_LSHIFT, ui::EF_NONE)));
761     EXPECT_FALSE(ProcessWithContext(
762         ui::Accelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
763     EXPECT_FALSE(ProcessWithContext(
764         ReleaseAccelerator(ui::VKEY_RSHIFT, ui::EF_NONE)));
765     EXPECT_FALSE(ProcessWithContext(
766         ui::Accelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
767     EXPECT_FALSE(ProcessWithContext(
768         ReleaseAccelerator(ui::VKEY_SHIFT, ui::EF_NONE)));
769   }
770   // ToggleCapsLock
771   {
772     CapsLockDelegate* delegate = Shell::GetInstance()->caps_lock_delegate();
773     delegate->SetCapsLockEnabled(true);
774     EXPECT_TRUE(delegate->IsCapsLockEnabled());
775     EXPECT_FALSE(ProcessWithContext(
776         ui::Accelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)));
777     EXPECT_TRUE(ProcessWithContext(
778         ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)));
779     EXPECT_FALSE(delegate->IsCapsLockEnabled());
780     EXPECT_FALSE(ProcessWithContext(
781         ui::Accelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)));
782     EXPECT_TRUE(ProcessWithContext(
783         ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_ALT_DOWN)));
784     EXPECT_TRUE(delegate->IsCapsLockEnabled());
785   }
786   const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
787   const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
788   const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
789   {
790     DummyVolumeControlDelegate* delegate =
791         new DummyVolumeControlDelegate(false);
792     ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
793         scoped_ptr<VolumeControlDelegate>(delegate).Pass());
794     EXPECT_EQ(0, delegate->handle_volume_mute_count());
795     EXPECT_FALSE(ProcessWithContext(volume_mute));
796     EXPECT_EQ(1, delegate->handle_volume_mute_count());
797     EXPECT_EQ(volume_mute, delegate->last_accelerator());
798     EXPECT_EQ(0, delegate->handle_volume_down_count());
799     EXPECT_FALSE(ProcessWithContext(volume_down));
800     EXPECT_EQ(1, delegate->handle_volume_down_count());
801     EXPECT_EQ(volume_down, delegate->last_accelerator());
802     EXPECT_EQ(0, delegate->handle_volume_up_count());
803     EXPECT_FALSE(ProcessWithContext(volume_up));
804     EXPECT_EQ(1, delegate->handle_volume_up_count());
805     EXPECT_EQ(volume_up, delegate->last_accelerator());
806   }
807   {
808     DummyVolumeControlDelegate* delegate = new DummyVolumeControlDelegate(true);
809     ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
810         scoped_ptr<VolumeControlDelegate>(delegate).Pass());
811     EXPECT_EQ(0, delegate->handle_volume_mute_count());
812     EXPECT_TRUE(ProcessWithContext(volume_mute));
813     EXPECT_EQ(1, delegate->handle_volume_mute_count());
814     EXPECT_EQ(volume_mute, delegate->last_accelerator());
815     EXPECT_EQ(0, delegate->handle_volume_down_count());
816     EXPECT_TRUE(ProcessWithContext(volume_down));
817     EXPECT_EQ(1, delegate->handle_volume_down_count());
818     EXPECT_EQ(volume_down, delegate->last_accelerator());
819     EXPECT_EQ(0, delegate->handle_volume_up_count());
820     EXPECT_TRUE(ProcessWithContext(volume_up));
821     EXPECT_EQ(1, delegate->handle_volume_up_count());
822     EXPECT_EQ(volume_up, delegate->last_accelerator());
823   }
824 #if defined(OS_CHROMEOS)
825   // Brightness
826   // ui::VKEY_BRIGHTNESS_DOWN/UP are not defined on Windows.
827   const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
828   const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
829   {
830     EXPECT_FALSE(ProcessWithContext(brightness_down));
831     EXPECT_FALSE(ProcessWithContext(brightness_up));
832     DummyBrightnessControlDelegate* delegate =
833         new DummyBrightnessControlDelegate(true);
834     GetController()->SetBrightnessControlDelegate(
835         scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
836     EXPECT_FALSE(ProcessWithContext(brightness_down));
837     EXPECT_FALSE(ProcessWithContext(brightness_up));
838   }
839   // Enable internal display.
840   EnableInternalDisplay();
841   {
842     DummyBrightnessControlDelegate* delegate =
843         new DummyBrightnessControlDelegate(false);
844     GetController()->SetBrightnessControlDelegate(
845         scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
846     EXPECT_EQ(0, delegate->handle_brightness_down_count());
847     EXPECT_FALSE(ProcessWithContext(brightness_down));
848     EXPECT_EQ(1, delegate->handle_brightness_down_count());
849     EXPECT_EQ(brightness_down, delegate->last_accelerator());
850     EXPECT_EQ(0, delegate->handle_brightness_up_count());
851     EXPECT_FALSE(ProcessWithContext(brightness_up));
852     EXPECT_EQ(1, delegate->handle_brightness_up_count());
853     EXPECT_EQ(brightness_up, delegate->last_accelerator());
854   }
855   {
856     DummyBrightnessControlDelegate* delegate =
857         new DummyBrightnessControlDelegate(true);
858     GetController()->SetBrightnessControlDelegate(
859         scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
860     EXPECT_EQ(0, delegate->handle_brightness_down_count());
861     EXPECT_TRUE(ProcessWithContext(brightness_down));
862     EXPECT_EQ(1, delegate->handle_brightness_down_count());
863     EXPECT_EQ(brightness_down, delegate->last_accelerator());
864     EXPECT_EQ(0, delegate->handle_brightness_up_count());
865     EXPECT_TRUE(ProcessWithContext(brightness_up));
866     EXPECT_EQ(1, delegate->handle_brightness_up_count());
867     EXPECT_EQ(brightness_up, delegate->last_accelerator());
868   }
869
870   // Keyboard brightness
871   const ui::Accelerator alt_brightness_down(ui::VKEY_BRIGHTNESS_DOWN,
872                                             ui::EF_ALT_DOWN);
873   const ui::Accelerator alt_brightness_up(ui::VKEY_BRIGHTNESS_UP,
874                                           ui::EF_ALT_DOWN);
875   {
876     EXPECT_TRUE(ProcessWithContext(alt_brightness_down));
877     EXPECT_TRUE(ProcessWithContext(alt_brightness_up));
878     DummyKeyboardBrightnessControlDelegate* delegate =
879         new DummyKeyboardBrightnessControlDelegate(false);
880     GetController()->SetKeyboardBrightnessControlDelegate(
881         scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
882     EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
883     EXPECT_FALSE(ProcessWithContext(alt_brightness_down));
884     EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
885     EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
886     EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
887     EXPECT_FALSE(ProcessWithContext(alt_brightness_up));
888     EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
889     EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
890   }
891   {
892     DummyKeyboardBrightnessControlDelegate* delegate =
893         new DummyKeyboardBrightnessControlDelegate(true);
894     GetController()->SetKeyboardBrightnessControlDelegate(
895         scoped_ptr<KeyboardBrightnessControlDelegate>(delegate).Pass());
896     EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
897     EXPECT_TRUE(ProcessWithContext(alt_brightness_down));
898     EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
899     EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
900     EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
901     EXPECT_TRUE(ProcessWithContext(alt_brightness_up));
902     EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
903     EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
904   }
905 #endif
906
907 #if !defined(NDEBUG)
908   // ToggleDesktopBackgroundMode
909   EXPECT_TRUE(ProcessWithContext(
910       ui::Accelerator(ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)));
911 #if !defined(OS_LINUX)
912   // ToggleDesktopFullScreen (not implemented yet on Linux)
913   EXPECT_TRUE(ProcessWithContext(
914       ui::Accelerator(ui::VKEY_F11, ui::EF_CONTROL_DOWN)));
915 #endif  // OS_LINUX
916 #endif  // !NDEBUG
917
918 #if !defined(OS_WIN)
919   // Exit
920   ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
921   ASSERT_TRUE(!!ewh);
922   StubForTest(ewh);
923   EXPECT_TRUE(is_idle(ewh));
924   EXPECT_FALSE(is_ui_shown(ewh));
925   EXPECT_TRUE(ProcessWithContext(
926       ui::Accelerator(ui::VKEY_Q, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
927   EXPECT_FALSE(is_idle(ewh));
928   EXPECT_TRUE(is_ui_shown(ewh));
929   SimulateTimerExpired(ewh);
930   EXPECT_TRUE(is_idle(ewh));
931   EXPECT_FALSE(is_ui_shown(ewh));
932   Reset(ewh);
933 #endif
934
935   // New tab
936   EXPECT_TRUE(ProcessWithContext(
937       ui::Accelerator(ui::VKEY_T, ui::EF_CONTROL_DOWN)));
938
939   // New incognito window
940   EXPECT_TRUE(ProcessWithContext(
941       ui::Accelerator(ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
942
943   // New window
944   EXPECT_TRUE(ProcessWithContext(
945       ui::Accelerator(ui::VKEY_N, ui::EF_CONTROL_DOWN)));
946
947   // Restore tab
948   EXPECT_TRUE(ProcessWithContext(
949       ui::Accelerator(ui::VKEY_T, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
950
951   // Show task manager
952   EXPECT_TRUE(ProcessWithContext(
953       ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN)));
954
955 #if defined(OS_CHROMEOS)
956   // Open file manager
957   EXPECT_TRUE(ProcessWithContext(
958       ui::Accelerator(ui::VKEY_M, ui::EF_SHIFT_DOWN  | ui::EF_ALT_DOWN)));
959
960   // Lock screen
961   // NOTE: Accelerators that do not work on the lock screen need to be
962   // tested before the sequence below is invoked because it causes a side
963   // effect of locking the screen.
964   EXPECT_TRUE(ProcessWithContext(
965       ui::Accelerator(ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
966 #endif
967 }
968
969 TEST_F(AcceleratorControllerTest, GlobalAcceleratorsToggleAppList) {
970   AccessibilityDelegate* delegate =
971           ash::Shell::GetInstance()->accessibility_delegate();
972   EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
973
974   // The press event should not open the AppList, the release should instead.
975   EXPECT_FALSE(ProcessWithContext(
976       ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
977   EXPECT_TRUE(ProcessWithContext(
978       ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
979   EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
980
981   // When spoken feedback is on, the AppList should not toggle.
982   delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
983   EXPECT_FALSE(ProcessWithContext(
984       ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
985   EXPECT_FALSE(ProcessWithContext(
986       ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
987   delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
988   EXPECT_TRUE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
989
990   EXPECT_FALSE(ProcessWithContext(
991       ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
992   EXPECT_TRUE(ProcessWithContext(
993       ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
994   EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
995
996   // When spoken feedback is on, the AppList should not toggle.
997   delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
998   EXPECT_FALSE(ProcessWithContext(
999       ui::Accelerator(ui::VKEY_LWIN, ui::EF_NONE)));
1000   EXPECT_FALSE(ProcessWithContext(
1001       ReleaseAccelerator(ui::VKEY_LWIN, ui::EF_NONE)));
1002   delegate->ToggleSpokenFeedback(A11Y_NOTIFICATION_NONE);
1003   EXPECT_FALSE(ash::Shell::GetInstance()->GetAppListTargetVisibility());
1004 }
1005
1006 TEST_F(AcceleratorControllerTest, ImeGlobalAccelerators) {
1007   // Test IME shortcuts.
1008   {
1009     const ui::Accelerator control_space(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
1010     const ui::Accelerator convert(ui::VKEY_CONVERT, ui::EF_NONE);
1011     const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, ui::EF_NONE);
1012     const ui::Accelerator wide_half_1(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE);
1013     const ui::Accelerator wide_half_2(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE);
1014     const ui::Accelerator hangul(ui::VKEY_HANGUL, ui::EF_NONE);
1015     EXPECT_FALSE(ProcessWithContext(control_space));
1016     EXPECT_FALSE(ProcessWithContext(convert));
1017     EXPECT_FALSE(ProcessWithContext(non_convert));
1018     EXPECT_FALSE(ProcessWithContext(wide_half_1));
1019     EXPECT_FALSE(ProcessWithContext(wide_half_2));
1020     EXPECT_FALSE(ProcessWithContext(hangul));
1021     DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
1022     GetController()->SetImeControlDelegate(
1023         scoped_ptr<ImeControlDelegate>(delegate).Pass());
1024     EXPECT_EQ(0, delegate->handle_previous_ime_count());
1025     EXPECT_TRUE(ProcessWithContext(control_space));
1026     EXPECT_EQ(1, delegate->handle_previous_ime_count());
1027     EXPECT_EQ(0, delegate->handle_switch_ime_count());
1028     EXPECT_TRUE(ProcessWithContext(convert));
1029     EXPECT_EQ(1, delegate->handle_switch_ime_count());
1030     EXPECT_TRUE(ProcessWithContext(non_convert));
1031     EXPECT_EQ(2, delegate->handle_switch_ime_count());
1032     EXPECT_TRUE(ProcessWithContext(wide_half_1));
1033     EXPECT_EQ(3, delegate->handle_switch_ime_count());
1034     EXPECT_TRUE(ProcessWithContext(wide_half_2));
1035     EXPECT_EQ(4, delegate->handle_switch_ime_count());
1036     EXPECT_TRUE(ProcessWithContext(hangul));
1037     EXPECT_EQ(5, delegate->handle_switch_ime_count());
1038   }
1039
1040   // Test IME shortcuts that are triggered on key release.
1041   {
1042     const ui::Accelerator shift_alt_press(ui::VKEY_MENU,
1043                                           ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1044     const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1045     const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT,
1046                                           ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1047     const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1048
1049     DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
1050     GetController()->SetImeControlDelegate(
1051         scoped_ptr<ImeControlDelegate>(delegate).Pass());
1052     EXPECT_EQ(0, delegate->handle_next_ime_count());
1053     EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1054     EXPECT_TRUE(ProcessWithContext(shift_alt));
1055     EXPECT_EQ(1, delegate->handle_next_ime_count());
1056     EXPECT_FALSE(ProcessWithContext(alt_shift_press));
1057     EXPECT_TRUE(ProcessWithContext(alt_shift));
1058     EXPECT_EQ(2, delegate->handle_next_ime_count());
1059
1060     // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1061     // released.
1062     const ui::Accelerator shift_alt_x_press(
1063         ui::VKEY_X,
1064         ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1065     const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
1066                                          ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1067
1068     EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1069     EXPECT_FALSE(ProcessWithContext(shift_alt_x_press));
1070     EXPECT_FALSE(ProcessWithContext(shift_alt_x));
1071     EXPECT_FALSE(ProcessWithContext(shift_alt));
1072     EXPECT_EQ(2, delegate->handle_next_ime_count());
1073
1074     // But we _should_ if X is either VKEY_RETURN or VKEY_SPACE.
1075     // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1076     const ui::Accelerator shift_alt_return_press(
1077         ui::VKEY_RETURN,
1078         ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1079     const ReleaseAccelerator shift_alt_return(
1080         ui::VKEY_RETURN,
1081         ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1082
1083     EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1084     EXPECT_FALSE(ProcessWithContext(shift_alt_return_press));
1085     EXPECT_FALSE(ProcessWithContext(shift_alt_return));
1086     EXPECT_TRUE(ProcessWithContext(shift_alt));
1087     EXPECT_EQ(3, delegate->handle_next_ime_count());
1088
1089     const ui::Accelerator shift_alt_space_press(
1090         ui::VKEY_SPACE,
1091         ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1092     const ReleaseAccelerator shift_alt_space(
1093         ui::VKEY_SPACE,
1094         ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1095
1096     EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1097     EXPECT_FALSE(ProcessWithContext(shift_alt_space_press));
1098     EXPECT_FALSE(ProcessWithContext(shift_alt_space));
1099     EXPECT_TRUE(ProcessWithContext(shift_alt));
1100     EXPECT_EQ(4, delegate->handle_next_ime_count());
1101   }
1102
1103 #if defined(OS_CHROMEOS)
1104   // Test IME shortcuts again with unnormalized accelerators (Chrome OS only).
1105   {
1106     const ui::Accelerator shift_alt_press(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1107     const ReleaseAccelerator shift_alt(ui::VKEY_MENU, ui::EF_SHIFT_DOWN);
1108     const ui::Accelerator alt_shift_press(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1109     const ReleaseAccelerator alt_shift(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);
1110
1111     DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true);
1112     GetController()->SetImeControlDelegate(
1113         scoped_ptr<ImeControlDelegate>(delegate).Pass());
1114     EXPECT_EQ(0, delegate->handle_next_ime_count());
1115     EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1116     EXPECT_TRUE(ProcessWithContext(shift_alt));
1117     EXPECT_EQ(1, delegate->handle_next_ime_count());
1118     EXPECT_FALSE(ProcessWithContext(alt_shift_press));
1119     EXPECT_TRUE(ProcessWithContext(alt_shift));
1120     EXPECT_EQ(2, delegate->handle_next_ime_count());
1121
1122     // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is
1123     // released.
1124     const ui::Accelerator shift_alt_x_press(
1125         ui::VKEY_X,
1126         ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1127     const ReleaseAccelerator shift_alt_x(ui::VKEY_X,
1128                                          ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1129
1130     EXPECT_FALSE(ProcessWithContext(shift_alt_press));
1131     EXPECT_FALSE(ProcessWithContext(shift_alt_x_press));
1132     EXPECT_FALSE(ProcessWithContext(shift_alt_x));
1133     EXPECT_FALSE(ProcessWithContext(shift_alt));
1134     EXPECT_EQ(2, delegate->handle_next_ime_count());
1135   }
1136 #endif
1137 }
1138
1139 // TODO(nona|mazda): Remove this when crbug.com/139556 in a better way.
1140 TEST_F(AcceleratorControllerTest, ImeGlobalAcceleratorsWorkaround139556) {
1141   // The workaround for crbug.com/139556 depends on the fact that we don't
1142   // use Shift+Alt+Enter/Space with ET_KEY_PRESSED as an accelerator. Test it.
1143   const ui::Accelerator shift_alt_return_press(
1144       ui::VKEY_RETURN,
1145       ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1146   EXPECT_FALSE(ProcessWithContext(shift_alt_return_press));
1147   const ui::Accelerator shift_alt_space_press(
1148       ui::VKEY_SPACE,
1149       ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
1150   EXPECT_FALSE(ProcessWithContext(shift_alt_space_press));
1151 }
1152
1153 TEST_F(AcceleratorControllerTest, ReservedAccelerators) {
1154   // (Shift+)Alt+Tab and Chrome OS top-row keys are reserved.
1155   EXPECT_TRUE(GetController()->IsReservedAccelerator(
1156       ui::Accelerator(ui::VKEY_TAB, ui::EF_ALT_DOWN)));
1157   EXPECT_TRUE(GetController()->IsReservedAccelerator(
1158       ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)));
1159 #if defined(OS_CHROMEOS)
1160   EXPECT_TRUE(GetController()->IsReservedAccelerator(
1161       ui::Accelerator(ui::VKEY_POWER, ui::EF_NONE)));
1162 #endif
1163   // Others are not reserved.
1164   EXPECT_FALSE(GetController()->IsReservedAccelerator(
1165       ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1166   EXPECT_FALSE(GetController()->IsReservedAccelerator(
1167       ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE)));
1168   EXPECT_FALSE(GetController()->IsReservedAccelerator(
1169       ui::Accelerator(ui::VKEY_A, ui::EF_NONE)));
1170 }
1171
1172 #if defined(OS_CHROMEOS)
1173 TEST_F(AcceleratorControllerTest, DisallowedAtModalWindow) {
1174   std::set<AcceleratorAction> all_actions;
1175   for (size_t i = 0 ; i < kAcceleratorDataLength; ++i)
1176     all_actions.insert(kAcceleratorData[i].action);
1177 #if !defined(NDEBUG)
1178   std::set<AcceleratorAction> all_desktop_actions;
1179   for (size_t i = 0 ; i < kDesktopAcceleratorDataLength; ++i)
1180     all_desktop_actions.insert(kDesktopAcceleratorData[i].action);
1181 #endif
1182
1183   std::set<AcceleratorAction> actionsAllowedAtModalWindow;
1184   for (size_t k = 0 ; k < kActionsAllowedAtModalWindowLength; ++k)
1185     actionsAllowedAtModalWindow.insert(kActionsAllowedAtModalWindow[k]);
1186   for (std::set<AcceleratorAction>::const_iterator it =
1187            actionsAllowedAtModalWindow.begin();
1188        it != actionsAllowedAtModalWindow.end(); ++it) {
1189     EXPECT_TRUE(all_actions.find(*it) != all_actions.end()
1190
1191 #if !defined(NDEBUG)
1192                 || all_desktop_actions.find(*it) != all_desktop_actions.end()
1193 #endif
1194                 )
1195         << " action from kActionsAllowedAtModalWindow"
1196         << " not found in kAcceleratorData or kDesktopAcceleratorData. "
1197         << "action: " << *it;
1198   }
1199   scoped_ptr<aura::Window> window(
1200       CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
1201   const ui::Accelerator dummy;
1202   wm::ActivateWindow(window.get());
1203   Shell::GetInstance()->SimulateModalWindowOpenForTesting(true);
1204   for (std::set<AcceleratorAction>::const_iterator it = all_actions.begin();
1205        it != all_actions.end(); ++it) {
1206     if (actionsAllowedAtModalWindow.find(*it) ==
1207         actionsAllowedAtModalWindow.end()) {
1208       EXPECT_TRUE(GetController()->PerformAction(*it, dummy))
1209           << " for action (disallowed at modal window): " << *it;
1210     }
1211   }
1212   //  Testing of top row (F5-F10) accelerators that should still work
1213   //  when a modal window is open
1214   //
1215   // Screenshot
1216   {
1217     test::TestScreenshotDelegate* delegate = GetScreenshotDelegate();
1218     delegate->set_can_take_screenshot(false);
1219     EXPECT_TRUE(ProcessWithContext(
1220         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1221     EXPECT_TRUE(ProcessWithContext(
1222         ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1223     EXPECT_TRUE(ProcessWithContext(
1224         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
1225                         ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1226     delegate->set_can_take_screenshot(true);
1227     EXPECT_EQ(0, delegate->handle_take_screenshot_count());
1228     EXPECT_TRUE(ProcessWithContext(
1229         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_CONTROL_DOWN)));
1230     EXPECT_EQ(1, delegate->handle_take_screenshot_count());
1231     EXPECT_TRUE(ProcessWithContext(
1232         ui::Accelerator(ui::VKEY_PRINT, ui::EF_NONE)));
1233     EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1234     EXPECT_TRUE(ProcessWithContext(
1235         ui::Accelerator(ui::VKEY_MEDIA_LAUNCH_APP1,
1236         ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
1237     EXPECT_EQ(2, delegate->handle_take_screenshot_count());
1238   }
1239   // Brightness
1240   const ui::Accelerator brightness_down(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
1241   const ui::Accelerator brightness_up(ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE);
1242   {
1243     EXPECT_FALSE(ProcessWithContext(brightness_down));
1244     EXPECT_FALSE(ProcessWithContext(brightness_up));
1245     DummyBrightnessControlDelegate* delegate =
1246         new DummyBrightnessControlDelegate(true);
1247     GetController()->SetBrightnessControlDelegate(
1248         scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1249     EXPECT_FALSE(ProcessWithContext(brightness_down));
1250     EXPECT_FALSE(ProcessWithContext(brightness_up));
1251   }
1252   EnableInternalDisplay();
1253   {
1254     EXPECT_FALSE(ProcessWithContext(brightness_down));
1255     EXPECT_FALSE(ProcessWithContext(brightness_up));
1256     DummyBrightnessControlDelegate* delegate =
1257         new DummyBrightnessControlDelegate(false);
1258     GetController()->SetBrightnessControlDelegate(
1259         scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1260     EXPECT_EQ(0, delegate->handle_brightness_down_count());
1261     EXPECT_FALSE(ProcessWithContext(brightness_down));
1262     EXPECT_EQ(1, delegate->handle_brightness_down_count());
1263     EXPECT_EQ(brightness_down, delegate->last_accelerator());
1264     EXPECT_EQ(0, delegate->handle_brightness_up_count());
1265     EXPECT_FALSE(ProcessWithContext(brightness_up));
1266     EXPECT_EQ(1, delegate->handle_brightness_up_count());
1267     EXPECT_EQ(brightness_up, delegate->last_accelerator());
1268   }
1269   {
1270     DummyBrightnessControlDelegate* delegate =
1271         new DummyBrightnessControlDelegate(true);
1272     GetController()->SetBrightnessControlDelegate(
1273         scoped_ptr<BrightnessControlDelegate>(delegate).Pass());
1274     EXPECT_EQ(0, delegate->handle_brightness_down_count());
1275     EXPECT_TRUE(ProcessWithContext(brightness_down));
1276     EXPECT_EQ(1, delegate->handle_brightness_down_count());
1277     EXPECT_EQ(brightness_down, delegate->last_accelerator());
1278     EXPECT_EQ(0, delegate->handle_brightness_up_count());
1279     EXPECT_TRUE(ProcessWithContext(brightness_up));
1280     EXPECT_EQ(1, delegate->handle_brightness_up_count());
1281     EXPECT_EQ(brightness_up, delegate->last_accelerator());
1282   }
1283   // Volume
1284   const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
1285   const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
1286   const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
1287   {
1288     EXPECT_TRUE(ProcessWithContext(volume_mute));
1289     EXPECT_TRUE(ProcessWithContext(volume_down));
1290     EXPECT_TRUE(ProcessWithContext(volume_up));
1291     DummyVolumeControlDelegate* delegate =
1292         new DummyVolumeControlDelegate(false);
1293     ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1294         scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1295     EXPECT_EQ(0, delegate->handle_volume_mute_count());
1296     EXPECT_FALSE(ProcessWithContext(volume_mute));
1297     EXPECT_EQ(1, delegate->handle_volume_mute_count());
1298     EXPECT_EQ(volume_mute, delegate->last_accelerator());
1299     EXPECT_EQ(0, delegate->handle_volume_down_count());
1300     EXPECT_FALSE(ProcessWithContext(volume_down));
1301     EXPECT_EQ(1, delegate->handle_volume_down_count());
1302     EXPECT_EQ(volume_down, delegate->last_accelerator());
1303     EXPECT_EQ(0, delegate->handle_volume_up_count());
1304     EXPECT_FALSE(ProcessWithContext(volume_up));
1305     EXPECT_EQ(1, delegate->handle_volume_up_count());
1306     EXPECT_EQ(volume_up, delegate->last_accelerator());
1307   }
1308   {
1309     DummyVolumeControlDelegate* delegate = new DummyVolumeControlDelegate(true);
1310     ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
1311         scoped_ptr<VolumeControlDelegate>(delegate).Pass());
1312     EXPECT_EQ(0, delegate->handle_volume_mute_count());
1313     EXPECT_TRUE(ProcessWithContext(volume_mute));
1314     EXPECT_EQ(1, delegate->handle_volume_mute_count());
1315     EXPECT_EQ(volume_mute, delegate->last_accelerator());
1316     EXPECT_EQ(0, delegate->handle_volume_down_count());
1317     EXPECT_TRUE(ProcessWithContext(volume_down));
1318     EXPECT_EQ(1, delegate->handle_volume_down_count());
1319     EXPECT_EQ(volume_down, delegate->last_accelerator());
1320     EXPECT_EQ(0, delegate->handle_volume_up_count());
1321     EXPECT_TRUE(ProcessWithContext(volume_up));
1322     EXPECT_EQ(1, delegate->handle_volume_up_count());
1323     EXPECT_EQ(volume_up, delegate->last_accelerator());
1324   }
1325 }
1326 #endif
1327
1328 }  // namespace ash