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