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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/client/key_event_mapper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/proto/event.pb.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/protocol_mock_objects.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::ExpectationSet;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::InSequence;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using protocol::InputStub;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using protocol::KeyEvent;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using protocol::MockInputStub;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A hardcoded value used to verify |lock_states| is preserved.
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const uint32 kTestLockStates = protocol::KeyEvent::LOCK_STATES_CAPSLOCK;
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MATCHER_P2(EqualsUsbEvent, usb_keycode, pressed, "") {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return arg.usb_keycode() == static_cast<uint32>(usb_keycode) &&
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         arg.pressed() == pressed &&
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         // |lock_states| is hardcoded to kTestLockStates in all key events.
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         arg.lock_states() == kTestLockStates;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMATCHER_P2(EqualsUsbEventLockStates, usb_keycode, pressed, "") {
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return arg.usb_keycode() == static_cast<uint32>(usb_keycode) &&
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         arg.pressed() == pressed &&
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         arg.lock_states() == kTestLockStates;
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic KeyEvent NewUsbEvent(uint32 usb_keycode,
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                            bool pressed,
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                            uint32 lock_states) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyEvent event;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.set_usb_keycode(usb_keycode);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event.set_pressed(pressed);
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  event.set_lock_states(lock_states);
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return event;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic void PressAndReleaseUsb(InputStub* input_stub, uint32 usb_keycode) {
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  input_stub->InjectKeyEvent(NewUsbEvent(usb_keycode, true, kTestLockStates));
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  input_stub->InjectKeyEvent(NewUsbEvent(usb_keycode, false, kTestLockStates));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void InjectTestSequence(InputStub* input_stub) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 1; i <= 5; ++i)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PressAndReleaseUsb(input_stub, i);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that keys are passed through the KeyEventMapper by default.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(KeyEventMapperTest, NoMappingOrTrapping) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockInputStub mock_stub;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyEventMapper event_mapper(&mock_stub);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 1; i <= 5; ++i) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(i, true)));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(i, false)));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, false)));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InjectTestSequence(&event_mapper);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PressAndReleaseUsb(&event_mapper, 3);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that USB keys are remapped at most once.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(KeyEventMapperTest, RemapKeys) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockInputStub mock_stub;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyEventMapper event_mapper(&mock_stub);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.RemapKey(3, 4);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.RemapKey(4, 3);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.RemapKey(5, 3);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true)));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false)));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(4, true)));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(4, false)));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, false)));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, false)));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InjectTestSequence(&event_mapper);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic void HandleTrappedKey(MockInputStub* stub, const KeyEvent& event) {
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  stub->InjectKeyEvent(event);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that trapped and mapped USB keys are trapped but not remapped.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(KeyEventMapperTest, TrapKeys) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockInputStub mock_stub;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockInputStub trap_stub;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyEventMapper event_mapper(&mock_stub);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyEventMapper::KeyTrapCallback callback =
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&HandleTrappedKey, base::Unretained(&trap_stub));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.SetTrapCallback(callback);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.TrapKey(4, true);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.TrapKey(5, true);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.RemapKey(3, 4);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.RemapKey(4, 3);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_mapper.RemapKey(5, 3);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true)));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false)));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(4, true)));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(4, false)));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(trap_stub, InjectKeyEvent(EqualsUsbEvent(4, true)));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(trap_stub, InjectKeyEvent(EqualsUsbEvent(4, false)));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(trap_stub, InjectKeyEvent(EqualsUsbEvent(5, true)));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(trap_stub, InjectKeyEvent(EqualsUsbEvent(5, false)));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InjectTestSequence(&event_mapper);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace remoting
144