Chromium Code Reviews| 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, | |
| 19 0x09, 0x06, | |
| 20 0xA1, 0x01, | |
| 21 0x05, 0x07, | |
| 22 0x19, 0xE0, | |
| 23 0x29, 0xE7, | |
| 24 0x15, 0x00, | |
| 25 0x25, 0x01, | |
| 26 0x75, 0x01, | |
| 27 0x95, 0x08, | |
| 28 0x81, 0x02, | |
| 29 0x95, 0x01, | |
| 30 0x75, 0x08, | |
| 31 0x81, 0x01, | |
| 32 0x95, 0x05, | |
| 33 0x75, 0x01, | |
| 34 0x05, 0x08, | |
| 35 0x19, 0x01, | |
| 36 0x29, 0x05, | |
| 37 0x91, 0x02, | |
| 38 0x95, 0x01, | |
| 39 0x75, 0x03, | |
| 40 0x91, 0x01, | |
| 41 0x95, 0x06, | |
| 42 0x75, 0x08, | |
| 43 0x15, 0x00, | |
| 44 0x25, 0x65, | |
| 45 0x05, 0x07, | |
| 46 0x19, 0x00, | |
| 47 0x29, 0x65, | |
| 48 0x81, 0x00, | |
| 49 0xC0 | |
| 50 }; | |
| 51 | |
| 52 // See 'E.10 Report Descriptor (Mouse)' | |
| 53 // in HID specifications (v1.11) | |
| 54 const uint8_t kMouse[] = { | |
| 55 0x05, 0x01, | |
| 56 0x09, 0x02, | |
| 57 0xA1, 0x01, | |
| 58 0x09, 0x01, | |
| 59 0xA1, 0x00, | |
| 60 0x05, 0x09, | |
| 61 0x19, 0x01, | |
| 62 0x29, 0x03, | |
| 63 0x15, 0x00, | |
| 64 0x25, 0x01, | |
| 65 0x95, 0x03, | |
| 66 0x75, 0x01, | |
| 67 0x81, 0x02, | |
| 68 0x95, 0x01, | |
| 69 0x75, 0x05, | |
| 70 0x81, 0x01, | |
| 71 0x05, 0x01, | |
| 72 0x09, 0x30, | |
| 73 0x09, 0x31, | |
| 74 0x15, 0x81, | |
| 75 0x25, 0x7F, | |
| 76 0x75, 0x08, | |
| 77 0x95, 0x02, | |
| 78 0x81, 0x06, | |
| 79 0xC0, | |
| 80 0xC0 | |
| 81 }; | |
| 82 | |
| 83 const uint8_t kLogitechUnifyingReceiver[] = { | |
| 84 0x06, 0x00, 0xFF, | |
| 85 0x09, 0x01, | |
| 86 0xA1, 0x01, | |
| 87 0x85, 0x10, | |
| 88 0x75, 0x08, | |
| 89 0x95, 0x06, | |
| 90 0x15, 0x00, | |
| 91 0x26, 0xFF, 0x00, | |
| 92 0x09, 0x01, | |
| 93 0x81, 0x00, | |
| 94 0x09, 0x01, | |
| 95 0x91, 0x00, | |
| 96 0xC0, | |
| 97 0x06, 0x00, 0xFF, | |
| 98 0x09, 0x02, | |
| 99 0xA1, 0x01, | |
| 100 0x85, 0x11, | |
| 101 0x75, 0x08, | |
| 102 0x95, 0x13, | |
| 103 0x15, 0x00, | |
| 104 0x26, 0xFF, 0x00, | |
| 105 0x09, 0x02, | |
| 106 0x81, 0x00, | |
| 107 0x09, 0x02, | |
| 108 0x91, 0x00, | |
| 109 0xC0, | |
| 110 0x06, 0x00, 0xFF, | |
| 111 0x09, 0x04, | |
| 112 0xA1, 0x01, | |
| 113 0x85, 0x20, | |
| 114 0x75, 0x08, | |
| 115 0x95, 0x0E, | |
| 116 0x15, 0x00, | |
| 117 0x26, 0xFF, 0x00, | |
| 118 0x09, 0x41, | |
| 119 0x81, 0x00, | |
| 120 0x09, 0x41, | |
| 121 0x91, 0x00, | |
| 122 0x85, 0x21, | |
| 123 0x95, 0x1F, | |
| 124 0x15, 0x00, | |
| 125 0x26, 0xFF, 0x00, | |
| 126 0x09, 0x42, | |
| 127 0x81, 0x00, | |
| 128 0x09, 0x42, | |
| 129 0x91, 0x00, | |
| 130 0xC0 | |
| 131 }; | |
| 132 | |
| 133 } // namespace | |
| 134 | |
| 135 class HidReportDescriptorTest : public testing::Test { | |
| 136 protected: | |
| 137 virtual void SetUp() OVERRIDE { | |
| 138 descriptor_ = NULL; | |
| 139 } | |
| 140 | |
| 141 virtual void TearDown() OVERRIDE { | |
| 142 if (descriptor_) { | |
| 143 delete descriptor_; | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 public: | |
| 148 void ParseDescriptor(const std::string& parsed_expected, | |
| 149 const uint8_t *bytes, | |
| 150 size_t size) { | |
| 151 | |
| 152 descriptor_ = new HidReportDescriptor(bytes, size); | |
| 153 | |
| 154 std::stringstream parsed_actual; | |
| 155 parsed_actual << *descriptor_; | |
| 156 | |
| 157 std::cout << "HID report descriptor:" << std::endl; | |
| 158 std::cout << *descriptor_; | |
| 159 | |
| 160 ASSERT_EQ(parsed_expected, parsed_actual.str()); | |
| 161 } | |
| 162 | |
| 163 void GetTopLevelCollections( | |
| 164 const std::vector<HidUsageAndPage>& tlcs_expected, | |
| 165 const uint8_t *bytes, | |
| 166 size_t size) { | |
| 167 | |
| 168 descriptor_ = new HidReportDescriptor(bytes, size); | |
| 169 | |
| 170 std::vector<HidUsageAndPage> tlcs_actual | |
| 171 = descriptor_->topLevelCollections(); | |
| 172 | |
| 173 std::cout << "HID top-level collections:" << std::endl; | |
| 174 for (std::vector<HidUsageAndPage>::const_iterator | |
| 175 tlcs_iter = tlcs_actual.begin(); | |
| 176 tlcs_iter != tlcs_actual.end(); | |
| 177 ++tlcs_iter) { | |
| 178 std::cout << *tlcs_iter << std::endl; | |
| 179 } | |
| 180 | |
| 181 ASSERT_THAT(tlcs_actual, ContainerEq(tlcs_expected)); | |
| 182 } | |
| 183 | |
| 184 private: | |
| 185 HidReportDescriptor* descriptor_; | |
| 186 }; | |
| 187 | |
| 188 TEST_F(HidReportDescriptorTest, ParseDescriptor_Keyboard) { | |
| 189 | |
| 190 const char parsed_expected[] = { | |
| 191 "Usage Page (Generic Desktop)\n" | |
| 192 "Usage (0x6)\n" | |
| 193 "Collection (Physical)\n" | |
| 194 " Usage Page (Keyboard)\n" | |
| 195 " Usage Minimum (0xE0)\n" | |
| 196 " Usage Maximum (0xE7)\n" | |
| 197 " Logical Minimum (0)\n" | |
| 198 " Logical Maximum (1)\n" | |
| 199 " Report Size (1)\n" | |
| 200 " Report Count (8)\n" | |
| 201 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 202 " Report Count (1)\n" | |
| 203 " Report Size (8)\n" | |
| 204 " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 205 " Report Count (5)\n" | |
| 206 " Report Size (1)\n" | |
| 207 " Usage Page (Led)\n" | |
| 208 " Usage Minimum (0x1)\n" | |
| 209 " Usage Maximum (0x5)\n" | |
| 210 " Output (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 211 " Report Count (1)\n" | |
| 212 " Report Size (3)\n" | |
| 213 " Output (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 214 " Report Count (6)\n" | |
| 215 " Report Size (8)\n" | |
| 216 " Logical Minimum (0)\n" | |
| 217 " Logical Maximum (101)\n" | |
| 218 " Usage Page (Keyboard)\n" | |
| 219 " Usage Minimum (0x0)\n" | |
| 220 " Usage Maximum (0x65)\n" | |
| 221 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 222 "End Collection\n" | |
| 223 }; | |
| 224 | |
| 225 ParseDescriptor(std::string(parsed_expected), | |
| 226 kKeyboard, | |
| 227 sizeof(kKeyboard)); | |
| 228 } | |
| 229 | |
| 230 TEST_F(HidReportDescriptorTest, TopLevelCollections_Keyboard) { | |
| 231 | |
| 232 HidUsageAndPage tlcs_expected[] = { | |
| 233 HidUsageAndPage(HidUsageAndPage::kPageGenericDesktop, 0x06) | |
| 234 }; | |
| 235 | |
| 236 GetTopLevelCollections(std::vector<HidUsageAndPage>( | |
| 237 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), | |
| 238 kKeyboard, | |
| 239 sizeof(kKeyboard)); | |
| 240 } | |
| 241 | |
| 242 TEST_F(HidReportDescriptorTest, ParseDescriptor_Mouse) { | |
| 243 | |
| 244 const char parsed_expected[] = { | |
| 245 "Usage Page (Generic Desktop)\n" | |
| 246 "Usage (0x2)\n" | |
| 247 "Collection (Physical)\n" | |
| 248 " Usage (0x1)\n" | |
| 249 " Collection (Physical)\n" | |
| 250 " Usage Page (Button)\n" | |
| 251 " Usage Minimum (0x1)\n" | |
| 252 " Usage Maximum (0x3)\n" | |
| 253 " Logical Minimum (0)\n" | |
| 254 " Logical Maximum (1)\n" | |
| 255 " Report Count (3)\n" | |
| 256 " Report Size (1)\n" | |
| 257 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 258 " Report Count (1)\n" | |
| 259 " Report Size (5)\n" | |
| 260 " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 261 " Usage Page (Generic Desktop)\n" | |
| 262 " Usage (0x30)\n" | |
| 263 " Usage (0x31)\n" | |
| 264 " Logical Minimum (129)\n" | |
| 265 " Logical Maximum (127)\n" | |
| 266 " Report Size (8)\n" | |
| 267 " Report Count (2)\n" | |
| 268 " Input (Dat|Arr|Abs|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 269 " End Collection\n" | |
| 270 "End Collection\n" | |
| 271 }; | |
| 272 | |
| 273 ParseDescriptor(std::string(parsed_expected), | |
| 274 kMouse, | |
| 275 sizeof(kMouse)); | |
| 276 } | |
| 277 | |
| 278 TEST_F(HidReportDescriptorTest, TopLevelCollections_Mouse) { | |
| 279 | |
| 280 HidUsageAndPage tlcs_expected[] = { | |
| 281 HidUsageAndPage(HidUsageAndPage::kPageGenericDesktop, 0x02) | |
| 282 }; | |
| 283 | |
| 284 GetTopLevelCollections(std::vector<HidUsageAndPage>( | |
| 285 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), | |
| 286 kMouse, | |
| 287 sizeof(kMouse)); | |
| 288 } | |
| 289 | |
| 290 TEST_F(HidReportDescriptorTest, ParseDescriptor_LogitechUnifyingReceiver) { | |
| 291 | |
| 292 const char parsed_expected[] = { | |
| 293 "Usage Page (Vendor)\n" | |
| 294 "Usage (0x1)\n" | |
| 295 "Collection (Physical)\n" | |
| 296 " Report ID (0x10)\n" | |
| 297 " Report Size (8)\n" | |
| 298 " Report Count (6)\n" | |
| 299 " Logical Minimum (0)\n" | |
| 300 " Logical Maximum (255)\n" | |
| 301 " Usage (0x1)\n" | |
| 302 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 303 " Usage (0x1)\n" | |
| 304 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 305 "End Collection\n" | |
| 306 "Usage Page (Vendor)\n" | |
| 307 "Usage (0x2)\n" | |
| 308 "Collection (Physical)\n" | |
| 309 " Report ID (0x11)\n" | |
| 310 " Report Size (8)\n" | |
| 311 " Report Count (19)\n" | |
| 312 " Logical Minimum (0)\n" | |
| 313 " Logical Maximum (255)\n" | |
| 314 " Usage (0x2)\n" | |
| 315 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 316 " Usage (0x2)\n" | |
| 317 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 318 "End Collection\n" | |
| 319 "Usage Page (Vendor)\n" | |
| 320 "Usage (0x4)\n" | |
| 321 "Collection (Physical)\n" | |
| 322 " Report ID (0x20)\n" | |
| 323 " Report Size (8)\n" | |
| 324 " Report Count (14)\n" | |
| 325 " Logical Minimum (0)\n" | |
| 326 " Logical Maximum (255)\n" | |
| 327 " Usage (0x41)\n" | |
| 328 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 329 " Usage (0x41)\n" | |
| 330 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 331 " Report ID (0x21)\n" | |
| 332 " Report Count (31)\n" | |
| 333 " Logical Minimum (0)\n" | |
| 334 " Logical Maximum (255)\n" | |
| 335 " Usage (0x42)\n" | |
| 336 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 337 " Usage (0x42)\n" | |
| 338 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" | |
| 339 "End Collection\n" | |
| 340 }; | |
| 341 | |
| 342 ParseDescriptor(std::string(parsed_expected), | |
| 343 kLogitechUnifyingReceiver, | |
| 344 sizeof(kLogitechUnifyingReceiver)); | |
| 345 } | |
| 346 | |
| 347 TEST_F(HidReportDescriptorTest, TopLevelCollections_LogitechUnifyingReceiver) { | |
| 348 | |
|
Ken Rockot(use gerrit already)
2014/04/15 17:53:38
nit: No need for vertical whitespace at the top of
| |
| 349 HidUsageAndPage tlcs_expected[] = { | |
| 350 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x01), | |
| 351 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x02), | |
| 352 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x04), | |
| 353 }; | |
| 354 | |
| 355 GetTopLevelCollections(std::vector<HidUsageAndPage>( | |
| 356 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), | |
| 357 kLogitechUnifyingReceiver, | |
| 358 sizeof(kLogitechUnifyingReceiver)); | |
| 359 } | |
| 360 | |
| 361 } // namespace device | |
| OLD | NEW |