1// Copyright 2014 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/sticky_keys/sticky_keys_overlay.h" 6 7#include "ash/shell.h" 8#include "ash/sticky_keys/sticky_keys_controller.h" 9#include "ash/test/ash_test_base.h" 10#include "base/memory/scoped_ptr.h" 11#include "ui/aura/window_tree_host.h" 12#include "ui/events/event.h" 13#include "ui/events/event_processor.h" 14 15namespace ash { 16 17class StickyKeysOverlayTest : public test::AshTestBase { 18 public: 19 StickyKeysOverlayTest() : 20 controller_(NULL), 21 overlay_(NULL) {} 22 23 virtual ~StickyKeysOverlayTest() {} 24 25 virtual void SetUp() OVERRIDE { 26 test::AshTestBase::SetUp(); 27 28 controller_ = Shell::GetInstance()->sticky_keys_controller(); 29 controller_->Enable(true); 30 overlay_ = controller_->GetOverlayForTest(); 31 ASSERT_TRUE(overlay_); 32 } 33 34 void PressAndReleaseKey(ui::KeyboardCode code) { 35 SendKeyEvent(ui::ET_KEY_PRESSED, code); 36 SendKeyEvent(ui::ET_KEY_RELEASED, code); 37 } 38 39 void SendKeyEvent(ui::EventType type, ui::KeyboardCode code) { 40 ui::KeyEvent event(type, code, 0, false); 41 ui::Event::DispatcherApi dispatcher(&event); 42 dispatcher.set_target(Shell::GetInstance()->GetPrimaryRootWindow()); 43 44 ui::EventDispatchDetails details = Shell::GetPrimaryRootWindow()-> 45 GetHost()->event_processor()->OnEventFromSource(&event); 46 CHECK(!details.dispatcher_destroyed); 47 } 48 49 StickyKeysController* controller_; 50 StickyKeysOverlay* overlay_; 51}; 52 53TEST_F(StickyKeysOverlayTest, OverlayVisibility) { 54 StickyKeysOverlay overlay; 55 EXPECT_FALSE(overlay.is_visible()); 56 overlay.Show(true); 57 EXPECT_TRUE(overlay.is_visible()); 58} 59 60TEST_F(StickyKeysOverlayTest, ModifierKeyState) { 61 StickyKeysOverlay overlay; 62 overlay.SetModifierKeyState(ui::EF_SHIFT_DOWN, STICKY_KEY_STATE_DISABLED); 63 overlay.SetModifierKeyState(ui::EF_ALT_DOWN, STICKY_KEY_STATE_LOCKED); 64 overlay.SetModifierKeyState(ui::EF_CONTROL_DOWN, STICKY_KEY_STATE_ENABLED); 65 66 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 67 overlay.GetModifierKeyState(ui::EF_SHIFT_DOWN)); 68 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, 69 overlay.GetModifierKeyState(ui::EF_ALT_DOWN)); 70 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, 71 overlay.GetModifierKeyState(ui::EF_CONTROL_DOWN)); 72} 73 74TEST_F(StickyKeysOverlayTest, OneModifierEnabled) { 75 EXPECT_FALSE(overlay_->is_visible()); 76 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 77 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 78 79 // Pressing modifier key should show overlay. 80 PressAndReleaseKey(ui::VKEY_CONTROL); 81 EXPECT_TRUE(overlay_->is_visible()); 82 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, 83 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 84 85 // Pressing a normal key should hide overlay. 86 PressAndReleaseKey(ui::VKEY_T); 87 EXPECT_FALSE(overlay_->is_visible()); 88 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 89 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 90} 91 92TEST_F(StickyKeysOverlayTest, TwoModifiersEnabled) { 93 EXPECT_FALSE(overlay_->is_visible()); 94 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 95 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 96 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 97 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 98 99 // Pressing two modifiers should show overlay. 100 PressAndReleaseKey(ui::VKEY_SHIFT); 101 PressAndReleaseKey(ui::VKEY_CONTROL); 102 EXPECT_TRUE(overlay_->is_visible()); 103 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, 104 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 105 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, 106 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 107 108 // Pressing a normal key should hide overlay. 109 PressAndReleaseKey(ui::VKEY_N); 110 EXPECT_FALSE(overlay_->is_visible()); 111 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 112 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 113 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 114 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 115} 116 117TEST_F(StickyKeysOverlayTest, LockedModifier) { 118 EXPECT_FALSE(overlay_->is_visible()); 119 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 120 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); 121 122 // Pressing a modifier key twice should lock modifier and show overlay. 123 PressAndReleaseKey(ui::VKEY_LMENU); 124 PressAndReleaseKey(ui::VKEY_LMENU); 125 EXPECT_TRUE(overlay_->is_visible()); 126 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, 127 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); 128 129 // Pressing a normal key should not hide overlay. 130 PressAndReleaseKey(ui::VKEY_D); 131 EXPECT_TRUE(overlay_->is_visible()); 132 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, 133 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); 134} 135 136TEST_F(StickyKeysOverlayTest, LockedAndNormalModifier) { 137 EXPECT_FALSE(overlay_->is_visible()); 138 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 139 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 140 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 141 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 142 143 // Pressing a modifier key twice should lock modifier and show overlay. 144 PressAndReleaseKey(ui::VKEY_CONTROL); 145 PressAndReleaseKey(ui::VKEY_CONTROL); 146 EXPECT_TRUE(overlay_->is_visible()); 147 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, 148 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 149 150 // Pressing another modifier key should still show overlay. 151 PressAndReleaseKey(ui::VKEY_SHIFT); 152 EXPECT_TRUE(overlay_->is_visible()); 153 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, 154 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 155 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, 156 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 157 158 // Pressing a normal key should not hide overlay but disable normal modifier. 159 PressAndReleaseKey(ui::VKEY_D); 160 EXPECT_TRUE(overlay_->is_visible()); 161 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, 162 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 163 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 164 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 165} 166 167TEST_F(StickyKeysOverlayTest, ModifiersDisabled) { 168 EXPECT_FALSE(overlay_->is_visible()); 169 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 170 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 171 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 172 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 173 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 174 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); 175 176 // Enable modifiers. 177 PressAndReleaseKey(ui::VKEY_CONTROL); 178 PressAndReleaseKey(ui::VKEY_SHIFT); 179 PressAndReleaseKey(ui::VKEY_SHIFT); 180 PressAndReleaseKey(ui::VKEY_LMENU); 181 182 EXPECT_TRUE(overlay_->is_visible()); 183 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, 184 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 185 EXPECT_EQ(STICKY_KEY_STATE_LOCKED, 186 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 187 EXPECT_EQ(STICKY_KEY_STATE_ENABLED, 188 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); 189 190 // Disable modifiers and overlay should be hidden. 191 PressAndReleaseKey(ui::VKEY_CONTROL); 192 PressAndReleaseKey(ui::VKEY_CONTROL); 193 PressAndReleaseKey(ui::VKEY_SHIFT); 194 PressAndReleaseKey(ui::VKEY_LMENU); 195 PressAndReleaseKey(ui::VKEY_LMENU); 196 197 EXPECT_FALSE(overlay_->is_visible()); 198 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 199 overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN)); 200 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 201 overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN)); 202 EXPECT_EQ(STICKY_KEY_STATE_DISABLED, 203 overlay_->GetModifierKeyState(ui::EF_ALT_DOWN)); 204} 205 206TEST_F(StickyKeysOverlayTest, ModifierVisibility) { 207 // All but AltGr and Mod3 should initially be visible. 208 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_CONTROL_DOWN)); 209 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_SHIFT_DOWN)); 210 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALT_DOWN)); 211 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN)); 212 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN)); 213 214 // Turn all modifiers on. 215 controller_->SetModifiersEnabled(true, true); 216 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_CONTROL_DOWN)); 217 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_SHIFT_DOWN)); 218 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALT_DOWN)); 219 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN)); 220 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN)); 221 222 // Turn off Mod3. 223 controller_->SetModifiersEnabled(false, true); 224 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN)); 225 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN)); 226 227 // Turn off AltGr. 228 controller_->SetModifiersEnabled(true, false); 229 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN)); 230 EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN)); 231 232 // Turn off AltGr and Mod3. 233 controller_->SetModifiersEnabled(false, false); 234 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN)); 235 EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN)); 236} 237 238} // namespace ash 239