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 "remoting/client/key_event_mapper.h" 6 7 #include "remoting/proto/event.pb.h" 8 #include "remoting/protocol/protocol_mock_objects.h" 9 #include "testing/gmock/include/gmock/gmock.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 using ::testing::_; 13 using ::testing::ExpectationSet; 14 using ::testing::InSequence; 15 16 namespace remoting { 17 18 using protocol::InputStub; 19 using protocol::KeyEvent; 20 using protocol::MockInputStub; 21 22 // A hardcoded value used to verify |lock_states| is preserved. 23 static const uint32 kTestLockStates = protocol::KeyEvent::LOCK_STATES_CAPSLOCK; 24 25 MATCHER_P2(EqualsUsbEvent, usb_keycode, pressed, "") { 26 return arg.usb_keycode() == static_cast<uint32>(usb_keycode) && 27 arg.pressed() == pressed && 28 // |lock_states| is hardcoded to kTestLockStates in all key events. 29 arg.lock_states() == kTestLockStates; 30 } 31 32 MATCHER_P2(EqualsUsbEventLockStates, usb_keycode, pressed, "") { 33 return arg.usb_keycode() == static_cast<uint32>(usb_keycode) && 34 arg.pressed() == pressed && 35 arg.lock_states() == kTestLockStates; 36 } 37 38 static KeyEvent NewUsbEvent(uint32 usb_keycode, 39 bool pressed, 40 uint32 lock_states) { 41 KeyEvent event; 42 event.set_usb_keycode(usb_keycode); 43 event.set_pressed(pressed); 44 event.set_lock_states(lock_states); 45 46 return event; 47 } 48 49 static void PressAndReleaseUsb(InputStub* input_stub, uint32 usb_keycode) { 50 input_stub->InjectKeyEvent(NewUsbEvent(usb_keycode, true, kTestLockStates)); 51 input_stub->InjectKeyEvent(NewUsbEvent(usb_keycode, false, kTestLockStates)); 52 } 53 54 static void InjectTestSequence(InputStub* input_stub) { 55 for (int i = 1; i <= 5; ++i) 56 PressAndReleaseUsb(input_stub, i); 57 } 58 59 // Verify that keys are passed through the KeyEventMapper by default. 60 TEST(KeyEventMapperTest, NoMappingOrTrapping) { 61 MockInputStub mock_stub; 62 KeyEventMapper event_mapper(&mock_stub); 63 64 { 65 InSequence s; 66 67 for (int i = 1; i <= 5; ++i) { 68 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(i, true))); 69 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(i, false))); 70 } 71 72 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true))); 73 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, false))); 74 } 75 76 InjectTestSequence(&event_mapper); 77 PressAndReleaseUsb(&event_mapper, 3); 78 } 79 80 // Verify that USB keys are remapped at most once. 81 TEST(KeyEventMapperTest, RemapKeys) { 82 MockInputStub mock_stub; 83 KeyEventMapper event_mapper(&mock_stub); 84 event_mapper.RemapKey(3, 4); 85 event_mapper.RemapKey(4, 3); 86 event_mapper.RemapKey(5, 3); 87 88 { 89 InSequence s; 90 91 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true))); 92 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false))); 93 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true))); 94 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false))); 95 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(4, true))); 96 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(4, false))); 97 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true))); 98 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, false))); 99 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true))); 100 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, false))); 101 } 102 103 InjectTestSequence(&event_mapper); 104 } 105 106 static void HandleTrappedKey(MockInputStub* stub, const KeyEvent& event) { 107 stub->InjectKeyEvent(event); 108 } 109 110 // Verify that trapped and mapped USB keys are trapped but not remapped. 111 TEST(KeyEventMapperTest, TrapKeys) { 112 MockInputStub mock_stub; 113 MockInputStub trap_stub; 114 KeyEventMapper event_mapper(&mock_stub); 115 KeyEventMapper::KeyTrapCallback callback = 116 base::Bind(&HandleTrappedKey, base::Unretained(&trap_stub)); 117 event_mapper.SetTrapCallback(callback); 118 event_mapper.TrapKey(4, true); 119 event_mapper.TrapKey(5, true); 120 event_mapper.RemapKey(3, 4); 121 event_mapper.RemapKey(4, 3); 122 event_mapper.RemapKey(5, 3); 123 124 { 125 InSequence s; 126 127 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true))); 128 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false))); 129 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true))); 130 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false))); 131 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(4, true))); 132 EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(4, false))); 133 134 EXPECT_CALL(trap_stub, InjectKeyEvent(EqualsUsbEvent(4, true))); 135 EXPECT_CALL(trap_stub, InjectKeyEvent(EqualsUsbEvent(4, false))); 136 EXPECT_CALL(trap_stub, InjectKeyEvent(EqualsUsbEvent(5, true))); 137 EXPECT_CALL(trap_stub, InjectKeyEvent(EqualsUsbEvent(5, false))); 138 } 139 140 InjectTestSequence(&event_mapper); 141 } 142 143 } // namespace remoting 144