Home | History | Annotate | Download | only in protocol
      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/protocol/input_event_tracker.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 namespace protocol {
     18 
     19 namespace {
     20 
     21 static const MouseEvent::MouseButton BUTTON_LEFT = MouseEvent::BUTTON_LEFT;
     22 static const MouseEvent::MouseButton BUTTON_RIGHT = MouseEvent::BUTTON_RIGHT;
     23 
     24 // A hardcoded value used to verify |lock_states| is preserved.
     25 static const uint32 kTestLockStates = protocol::KeyEvent::LOCK_STATES_CAPSLOCK;
     26 
     27 // Verify the usb key code and the "pressed" state.
     28 // Also verify that the event doesn't have |lock_states| set.
     29 MATCHER_P2(EqualsUsbEventWithoutLockStates, usb_keycode, pressed, "") {
     30   return arg.usb_keycode() == static_cast<uint32>(usb_keycode) &&
     31          arg.pressed() == pressed &&
     32          !arg.has_lock_states();
     33 }
     34 
     35 // Verify the usb key code, the "pressed" state, and the lock states.
     36 MATCHER_P2(EqualsUsbEvent, usb_keycode, pressed, "") {
     37   return arg.usb_keycode() == static_cast<uint32>(usb_keycode) &&
     38           arg.pressed() == pressed &&
     39           arg.lock_states() == kTestLockStates;
     40 }
     41 
     42 MATCHER_P4(EqualsMouseEvent, x, y, button, down, "") {
     43   return arg.x() == x && arg.y() == y && arg.button() == button &&
     44          arg.button_down() == down;
     45 }
     46 
     47 static KeyEvent NewUsbEvent(uint32 usb_keycode,
     48                             bool pressed) {
     49   KeyEvent event;
     50   event.set_usb_keycode(usb_keycode);
     51   event.set_pressed(pressed);
     52   // Create all key events with the hardcoded |lock_state| in this test.
     53   event.set_lock_states(kTestLockStates);
     54   return event;
     55 }
     56 
     57 static void PressAndReleaseUsb(InputStub* input_stub,
     58                                uint32 usb_keycode) {
     59   input_stub->InjectKeyEvent(NewUsbEvent(usb_keycode, true));
     60   input_stub->InjectKeyEvent(NewUsbEvent(usb_keycode, false));
     61 }
     62 
     63 static MouseEvent NewMouseEvent(int x, int y,
     64     MouseEvent::MouseButton button, bool down) {
     65   MouseEvent event;
     66   event.set_x(x);
     67   event.set_y(y);
     68   event.set_button(button);
     69   event.set_button_down(down);
     70   return event;
     71 }
     72 
     73 }
     74 
     75 // Verify that keys that were pressed and released aren't re-released.
     76 TEST(InputEventTrackerTest, NothingToRelease) {
     77   MockInputStub mock_stub;
     78   InputEventTracker input_tracker(&mock_stub);
     79 
     80   {
     81     InSequence s;
     82 
     83     EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true)));
     84     EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false)));
     85     EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
     86     EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
     87 
     88     EXPECT_CALL(mock_stub,
     89         InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT, true)));
     90     EXPECT_CALL(mock_stub,
     91         InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT, false)));
     92   }
     93 
     94   PressAndReleaseUsb(&input_tracker, 1);
     95   PressAndReleaseUsb(&input_tracker, 2);
     96 
     97   input_tracker.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT, true));
     98   input_tracker.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT, false));
     99 
    100   input_tracker.ReleaseAll();
    101 }
    102 
    103 // Verify that keys that were left pressed get released.
    104 TEST(InputEventTrackerTest, ReleaseAllKeys) {
    105   MockInputStub mock_stub;
    106   InputEventTracker input_tracker(&mock_stub);
    107   ExpectationSet injects;
    108 
    109   {
    110     InSequence s;
    111 
    112     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
    113     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true)));
    114     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false)));
    115     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
    116     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
    117 
    118     injects += EXPECT_CALL(mock_stub,
    119         InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_RIGHT, true)));
    120     injects += EXPECT_CALL(mock_stub,
    121         InjectMouseEvent(EqualsMouseEvent(0, 0, BUTTON_LEFT, true)));
    122     injects += EXPECT_CALL(mock_stub,
    123         InjectMouseEvent(EqualsMouseEvent(1, 1, BUTTON_LEFT, false)));
    124   }
    125 
    126   // The key should be released but |lock_states| should not be set.
    127   EXPECT_CALL(mock_stub,
    128               InjectKeyEvent(EqualsUsbEventWithoutLockStates(3, false)))
    129       .After(injects);
    130   EXPECT_CALL(mock_stub,
    131               InjectMouseEvent(EqualsMouseEvent(1, 1, BUTTON_RIGHT, false)))
    132       .After(injects);
    133 
    134   input_tracker.InjectKeyEvent(NewUsbEvent(3, true));
    135   PressAndReleaseUsb(&input_tracker, 1);
    136   PressAndReleaseUsb(&input_tracker, 2);
    137 
    138   input_tracker.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_RIGHT, true));
    139   input_tracker.InjectMouseEvent(NewMouseEvent(0, 0, BUTTON_LEFT, true));
    140   input_tracker.InjectMouseEvent(NewMouseEvent(1, 1, BUTTON_LEFT, false));
    141 
    142   EXPECT_FALSE(input_tracker.IsKeyPressed(1));
    143   EXPECT_FALSE(input_tracker.IsKeyPressed(2));
    144   EXPECT_TRUE(input_tracker.IsKeyPressed(3));
    145   EXPECT_EQ(1, input_tracker.PressedKeyCount());
    146 
    147   input_tracker.ReleaseAll();
    148 }
    149 
    150 // Verify that we track both USB-based key events correctly.
    151 TEST(InputEventTrackerTest, TrackUsbKeyEvents) {
    152   MockInputStub mock_stub;
    153   InputEventTracker input_tracker(&mock_stub);
    154   ExpectationSet injects;
    155 
    156   {
    157     InSequence s;
    158 
    159     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
    160     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(6, true)));
    161     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(7, true)));
    162     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(5, true)));
    163     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(5, true)));
    164     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
    165     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
    166   }
    167 
    168   // The key should be auto released with no |lock_states|.
    169   EXPECT_CALL(mock_stub,
    170               InjectKeyEvent(EqualsUsbEventWithoutLockStates(3, false)))
    171       .After(injects);
    172   EXPECT_CALL(mock_stub,
    173               InjectKeyEvent(EqualsUsbEventWithoutLockStates(6, false)))
    174       .After(injects);
    175   EXPECT_CALL(mock_stub,
    176               InjectKeyEvent(EqualsUsbEventWithoutLockStates(7, false)))
    177       .After(injects);
    178   EXPECT_CALL(mock_stub,
    179               InjectKeyEvent(EqualsUsbEventWithoutLockStates(5, false)))
    180       .After(injects);
    181 
    182   input_tracker.InjectKeyEvent(NewUsbEvent(3, true));
    183   input_tracker.InjectKeyEvent(NewUsbEvent(6, true));
    184   input_tracker.InjectKeyEvent(NewUsbEvent(7, true));
    185   input_tracker.InjectKeyEvent(NewUsbEvent(5, true));
    186   input_tracker.InjectKeyEvent(NewUsbEvent(5, true));
    187   PressAndReleaseUsb(&input_tracker, 2);
    188 
    189   EXPECT_FALSE(input_tracker.IsKeyPressed(1));
    190   EXPECT_FALSE(input_tracker.IsKeyPressed(2));
    191   EXPECT_TRUE(input_tracker.IsKeyPressed(3));
    192   EXPECT_TRUE(input_tracker.IsKeyPressed(5));
    193   EXPECT_TRUE(input_tracker.IsKeyPressed(6));
    194   EXPECT_TRUE(input_tracker.IsKeyPressed(7));
    195   EXPECT_EQ(4, input_tracker.PressedKeyCount());
    196 
    197   input_tracker.ReleaseAll();
    198 }
    199 
    200 // Verify that invalid events get passed through but not tracked.
    201 TEST(InputEventTrackerTest, InvalidEventsNotTracked) {
    202   MockInputStub mock_stub;
    203   InputEventTracker input_tracker(&mock_stub);
    204   ExpectationSet injects;
    205 
    206   {
    207     InSequence s;
    208 
    209     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(3, true)));
    210     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, true)));
    211     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(1, false)));
    212     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(_)).Times(2);
    213     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, true)));
    214     injects += EXPECT_CALL(mock_stub, InjectKeyEvent(EqualsUsbEvent(2, false)));
    215   }
    216 
    217   EXPECT_CALL(mock_stub,
    218               InjectKeyEvent(EqualsUsbEventWithoutLockStates(3, false)))
    219       .After(injects);
    220 
    221   input_tracker.InjectKeyEvent(NewUsbEvent(3, true));
    222   PressAndReleaseUsb(&input_tracker, 1);
    223 
    224   KeyEvent invalid_event1;
    225   invalid_event1.set_pressed(true);
    226   input_tracker.InjectKeyEvent(invalid_event1);
    227 
    228   KeyEvent invalid_event2;
    229   invalid_event2.set_usb_keycode(6);
    230   input_tracker.InjectKeyEvent(invalid_event2);
    231 
    232   PressAndReleaseUsb(&input_tracker, 2);
    233 
    234   EXPECT_FALSE(input_tracker.IsKeyPressed(1));
    235   EXPECT_FALSE(input_tracker.IsKeyPressed(2));
    236   EXPECT_TRUE(input_tracker.IsKeyPressed(3));
    237   EXPECT_EQ(1, input_tracker.PressedKeyCount());
    238 
    239   input_tracker.ReleaseAll();
    240 }
    241 
    242 }  // namespace protocol
    243 }  // namespace remoting
    244