15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/wm/core/accelerator_filter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/accelerators/accelerator_controller.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/accelerators/accelerator_delegate.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_window_ids.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/test/ash_test_base.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/test/test_screenshot_delegate.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_state.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/aura_test_base.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/test_windows.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/events/event.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef AshTestBase AcceleratorFilterTest;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests if AcceleratorFilter works without a focused window.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AcceleratorFilterTest, TestFilterWithoutFocus) {
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const TestScreenshotDelegate* delegate = GetScreenshotDelegate();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate->handle_take_screenshot_count());
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AcceleratorController calls ScreenshotDelegate::HandleTakeScreenshot() when
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // VKEY_PRINT is pressed. See kAcceleratorData[] in accelerator_controller.cc.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressKey(ui::VKEY_PRINT, 0);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->handle_take_screenshot_count());
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.ReleaseKey(ui::VKEY_PRINT, 0);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->handle_take_screenshot_count());
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests if AcceleratorFilter works as expected with a focused window.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AcceleratorFilterTest, TestFilterWithFocus) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::test::TestWindowDelegate test_delegate;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &test_delegate,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -1,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect()));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wm::ActivateWindow(window.get());
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const TestScreenshotDelegate* delegate = GetScreenshotDelegate();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate->handle_take_screenshot_count());
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AcceleratorFilter should ignore the key events since the root window is
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not focused.
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressKey(ui::VKEY_PRINT, 0);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate->handle_take_screenshot_count());
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.ReleaseKey(ui::VKEY_PRINT, 0);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate->handle_take_screenshot_count());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset window before |test_delegate| gets deleted.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window.reset();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests if AcceleratorFilter ignores the flag for Caps Lock.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AcceleratorFilterTest, TestCapsLockMask) {
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const TestScreenshotDelegate* delegate = GetScreenshotDelegate();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, delegate->handle_take_screenshot_count());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressKey(ui::VKEY_PRINT, 0);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->handle_take_screenshot_count());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.ReleaseKey(ui::VKEY_PRINT, 0);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->handle_take_screenshot_count());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if AcceleratorFilter ignores the mask for Caps Lock. Note that there
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is no ui::EF_ mask for Num Lock.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressKey(ui::VKEY_PRINT, ui::EF_CAPS_LOCK_DOWN);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate->handle_take_screenshot_count());
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.ReleaseKey(ui::VKEY_PRINT, ui::EF_CAPS_LOCK_DOWN);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate->handle_take_screenshot_count());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_CHROMEOS)
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tests if special hardware keys like brightness and volume are consumed as
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// expected by the shell.
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(AcceleratorFilterTest, CanConsumeSystemKeys) {
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ::wm::AcceleratorFilter filter(
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr< ::wm::AcceleratorDelegate>(new AcceleratorDelegate).Pass());
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Normal keys are not consumed.
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::KeyEvent press_a(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ui::Event::DispatcherApi dispatch_helper(&press_a);
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    dispatch_helper.set_target(root_window);
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  filter.OnKeyEvent(&press_a);
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(press_a.stopped_propagation());
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // System keys are directly consumed.
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui::KeyEvent press_mute(
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ET_KEY_PRESSED, ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ui::Event::DispatcherApi dispatch_helper(&press_mute);
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    dispatch_helper.set_target(root_window);
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  filter.OnKeyEvent(&press_mute);
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(press_mute.stopped_propagation());
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Setting a window property on the target allows system keys to pass through.
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(1));
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wm::GetWindowState(window.get())->set_can_consume_system_keys(true);
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui::KeyEvent press_volume_up(
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::ET_KEY_PRESSED, ui::VKEY_VOLUME_UP, ui::EF_NONE);
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui::Event::DispatcherApi dispatch_helper(&press_volume_up);
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dispatch_helper.set_target(window.get());
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  filter.OnKeyEvent(&press_volume_up);
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(press_volume_up.stopped_propagation());
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // System keys pass through to a child window if the parent (top level)
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // window has the property set.
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<aura::Window> child(CreateTestWindowInShellWithId(2));
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window->AddChild(child.get());
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dispatch_helper.set_target(child.get());
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  filter.OnKeyEvent(&press_volume_up);
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(press_volume_up.stopped_propagation());
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_CHROMEOS)
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace test
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
135