OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 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 "device/hid/hid_report_descriptor.h" |
| 6 #include "testing/gmock/include/gmock/gmock.h" |
| 7 #include "testing/gtest/include/gtest/gtest.h" |
| 8 |
| 9 using namespace testing; |
| 10 |
| 11 namespace device { |
| 12 |
| 13 namespace { |
| 14 |
| 15 // See 'E.6 Report Descriptor (Keyboard)' |
| 16 // in HID specifications (v1.11) |
| 17 const uint8_t kKeyboard[] = { |
| 18 0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0, 0x29, |
| 19 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, |
| 20 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05, 0x75, 0x01, 0x05, |
| 21 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, |
| 22 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, |
| 23 0x07, 0x19, 0x00, 0x29, 0x65, 0x81, 0x00, 0xC0}; |
| 24 |
| 25 // See 'E.10 Report Descriptor (Mouse)' |
| 26 // in HID specifications (v1.11) |
| 27 const uint8_t kMouse[] = {0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, |
| 28 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, |
| 29 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, |
| 30 0x01, 0x75, 0x05, 0x81, 0x01, 0x05, 0x01, 0x09, 0x30, |
| 31 0x09, 0x31, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, |
| 32 0x02, 0x81, 0x06, 0xC0, 0xC0}; |
| 33 |
| 34 const uint8_t kLogitechUnifyingReceiver[] = { |
| 35 0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x75, 0x08, |
| 36 0x95, 0x06, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x09, 0x01, 0x81, 0x00, |
| 37 0x09, 0x01, 0x91, 0x00, 0xC0, 0x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, |
| 38 0x01, 0x85, 0x11, 0x75, 0x08, 0x95, 0x13, 0x15, 0x00, 0x26, 0xFF, |
| 39 0x00, 0x09, 0x02, 0x81, 0x00, 0x09, 0x02, 0x91, 0x00, 0xC0, 0x06, |
| 40 0x00, 0xFF, 0x09, 0x04, 0xA1, 0x01, 0x85, 0x20, 0x75, 0x08, 0x95, |
| 41 0x0E, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x09, 0x41, 0x81, 0x00, 0x09, |
| 42 0x41, 0x91, 0x00, 0x85, 0x21, 0x95, 0x1F, 0x15, 0x00, 0x26, 0xFF, |
| 43 0x00, 0x09, 0x42, 0x81, 0x00, 0x09, 0x42, 0x91, 0x00, 0xC0}; |
| 44 |
| 45 } // namespace |
| 46 |
| 47 class HidReportDescriptorTest : public testing::Test { |
| 48 protected: |
| 49 virtual void SetUp() OVERRIDE { descriptor_ = NULL; } |
| 50 |
| 51 virtual void TearDown() OVERRIDE { |
| 52 if (descriptor_) { |
| 53 delete descriptor_; |
| 54 } |
| 55 } |
| 56 |
| 57 public: |
| 58 void ParseDescriptor(const std::string& parsed_expected, |
| 59 const uint8_t* bytes, |
| 60 size_t size) { |
| 61 |
| 62 descriptor_ = new HidReportDescriptor(bytes, size); |
| 63 |
| 64 std::stringstream parsed_actual; |
| 65 parsed_actual << *descriptor_; |
| 66 |
| 67 std::cout << "HID report descriptor:" << std::endl; |
| 68 std::cout << *descriptor_; |
| 69 |
| 70 ASSERT_EQ(parsed_expected, parsed_actual.str()); |
| 71 } |
| 72 |
| 73 void GetTopLevelCollections(const std::vector<HidUsageAndPage>& tlcs_expected, |
| 74 const uint8_t* bytes, |
| 75 size_t size) { |
| 76 |
| 77 descriptor_ = new HidReportDescriptor(bytes, size); |
| 78 |
| 79 std::vector<HidUsageAndPage> tlcs_actual = |
| 80 descriptor_->topLevelCollections(); |
| 81 |
| 82 std::cout << "HID top-level collections:" << std::endl; |
| 83 for (std::vector<HidUsageAndPage>::const_iterator tlcs_iter = |
| 84 tlcs_actual.begin(); |
| 85 tlcs_iter != tlcs_actual.end(); |
| 86 ++tlcs_iter) { |
| 87 std::cout << *tlcs_iter << std::endl; |
| 88 } |
| 89 |
| 90 ASSERT_THAT(tlcs_actual, ContainerEq(tlcs_expected)); |
| 91 } |
| 92 |
| 93 private: |
| 94 HidReportDescriptor* descriptor_; |
| 95 }; |
| 96 |
| 97 TEST_F(HidReportDescriptorTest, ParseDescriptor_Keyboard) { |
| 98 |
| 99 const char parsed_expected[] = { |
| 100 "Usage Page (Generic Desktop)\n" |
| 101 "Usage (0x6)\n" |
| 102 "Collection (Physical)\n" |
| 103 " Usage Page (Keyboard)\n" |
| 104 " Usage Minimum (0xE0)\n" |
| 105 " Usage Maximum (0xE7)\n" |
| 106 " Logical Minimum (0)\n" |
| 107 " Logical Maximum (1)\n" |
| 108 " Report Size (1)\n" |
| 109 " Report Count (8)\n" |
| 110 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 111 " Report Count (1)\n" |
| 112 " Report Size (8)\n" |
| 113 " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 114 " Report Count (5)\n" |
| 115 " Report Size (1)\n" |
| 116 " Usage Page (Led)\n" |
| 117 " Usage Minimum (0x1)\n" |
| 118 " Usage Maximum (0x5)\n" |
| 119 " Output (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 120 " Report Count (1)\n" |
| 121 " Report Size (3)\n" |
| 122 " Output (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 123 " Report Count (6)\n" |
| 124 " Report Size (8)\n" |
| 125 " Logical Minimum (0)\n" |
| 126 " Logical Maximum (101)\n" |
| 127 " Usage Page (Keyboard)\n" |
| 128 " Usage Minimum (0x0)\n" |
| 129 " Usage Maximum (0x65)\n" |
| 130 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 131 "End Collection\n"}; |
| 132 |
| 133 ParseDescriptor(std::string(parsed_expected), kKeyboard, sizeof(kKeyboard)); |
| 134 } |
| 135 |
| 136 TEST_F(HidReportDescriptorTest, TopLevelCollections_Keyboard) { |
| 137 |
| 138 HidUsageAndPage tlcs_expected[] = { |
| 139 HidUsageAndPage(HidUsageAndPage::kPageGenericDesktop, 0x06)}; |
| 140 |
| 141 GetTopLevelCollections( |
| 142 std::vector<HidUsageAndPage>( |
| 143 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| 144 kKeyboard, |
| 145 sizeof(kKeyboard)); |
| 146 } |
| 147 |
| 148 TEST_F(HidReportDescriptorTest, ParseDescriptor_Mouse) { |
| 149 |
| 150 const char parsed_expected[] = { |
| 151 "Usage Page (Generic Desktop)\n" |
| 152 "Usage (0x2)\n" |
| 153 "Collection (Physical)\n" |
| 154 " Usage (0x1)\n" |
| 155 " Collection (Physical)\n" |
| 156 " Usage Page (Button)\n" |
| 157 " Usage Minimum (0x1)\n" |
| 158 " Usage Maximum (0x3)\n" |
| 159 " Logical Minimum (0)\n" |
| 160 " Logical Maximum (1)\n" |
| 161 " Report Count (3)\n" |
| 162 " Report Size (1)\n" |
| 163 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 164 " Report Count (1)\n" |
| 165 " Report Size (5)\n" |
| 166 " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 167 " Usage Page (Generic Desktop)\n" |
| 168 " Usage (0x30)\n" |
| 169 " Usage (0x31)\n" |
| 170 " Logical Minimum (129)\n" |
| 171 " Logical Maximum (127)\n" |
| 172 " Report Size (8)\n" |
| 173 " Report Count (2)\n" |
| 174 " Input (Dat|Arr|Abs|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 175 " End Collection\n" |
| 176 "End Collection\n"}; |
| 177 |
| 178 ParseDescriptor(std::string(parsed_expected), kMouse, sizeof(kMouse)); |
| 179 } |
| 180 |
| 181 TEST_F(HidReportDescriptorTest, TopLevelCollections_Mouse) { |
| 182 |
| 183 HidUsageAndPage tlcs_expected[] = { |
| 184 HidUsageAndPage(HidUsageAndPage::kPageGenericDesktop, 0x02)}; |
| 185 |
| 186 GetTopLevelCollections( |
| 187 std::vector<HidUsageAndPage>( |
| 188 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| 189 kMouse, |
| 190 sizeof(kMouse)); |
| 191 } |
| 192 |
| 193 TEST_F(HidReportDescriptorTest, ParseDescriptor_LogitechUnifyingReceiver) { |
| 194 |
| 195 const char parsed_expected[] = { |
| 196 "Usage Page (Vendor)\n" |
| 197 "Usage (0x1)\n" |
| 198 "Collection (Physical)\n" |
| 199 " Report ID (0x10)\n" |
| 200 " Report Size (8)\n" |
| 201 " Report Count (6)\n" |
| 202 " Logical Minimum (0)\n" |
| 203 " Logical Maximum (255)\n" |
| 204 " Usage (0x1)\n" |
| 205 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 206 " Usage (0x1)\n" |
| 207 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 208 "End Collection\n" |
| 209 "Usage Page (Vendor)\n" |
| 210 "Usage (0x2)\n" |
| 211 "Collection (Physical)\n" |
| 212 " Report ID (0x11)\n" |
| 213 " Report Size (8)\n" |
| 214 " Report Count (19)\n" |
| 215 " Logical Minimum (0)\n" |
| 216 " Logical Maximum (255)\n" |
| 217 " Usage (0x2)\n" |
| 218 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 219 " Usage (0x2)\n" |
| 220 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 221 "End Collection\n" |
| 222 "Usage Page (Vendor)\n" |
| 223 "Usage (0x4)\n" |
| 224 "Collection (Physical)\n" |
| 225 " Report ID (0x20)\n" |
| 226 " Report Size (8)\n" |
| 227 " Report Count (14)\n" |
| 228 " Logical Minimum (0)\n" |
| 229 " Logical Maximum (255)\n" |
| 230 " Usage (0x41)\n" |
| 231 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 232 " Usage (0x41)\n" |
| 233 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 234 " Report ID (0x21)\n" |
| 235 " Report Count (31)\n" |
| 236 " Logical Minimum (0)\n" |
| 237 " Logical Maximum (255)\n" |
| 238 " Usage (0x42)\n" |
| 239 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 240 " Usage (0x42)\n" |
| 241 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 242 "End Collection\n"}; |
| 243 |
| 244 ParseDescriptor(std::string(parsed_expected), |
| 245 kLogitechUnifyingReceiver, |
| 246 sizeof(kLogitechUnifyingReceiver)); |
| 247 } |
| 248 |
| 249 TEST_F(HidReportDescriptorTest, TopLevelCollections_LogitechUnifyingReceiver) { |
| 250 |
| 251 HidUsageAndPage tlcs_expected[] = { |
| 252 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x01), |
| 253 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x02), |
| 254 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x04), }; |
| 255 |
| 256 GetTopLevelCollections( |
| 257 std::vector<HidUsageAndPage>( |
| 258 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| 259 kLogitechUnifyingReceiver, |
| 260 sizeof(kLogitechUnifyingReceiver)); |
| 261 } |
| 262 |
| 263 } // namespace device |
OLD | NEW |