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 <sstream> 6 7 #include "device/hid/hid_report_descriptor.h" 8 #include "testing/gmock/include/gmock/gmock.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 using namespace testing; 12 13 namespace device { 14 15 namespace { 16 17 // Digitizer descriptor from HID descriptor tool 18 // http://www.usb.org/developers/hidpage/dt2_4.zip 19 const uint8_t kDigitizer[] = { 20 0x05, 0x0d, // Usage Page (Digitizer) 21 0x09, 0x01, // Usage (0x1) 22 0xa1, 0x01, // Collection (Application) 23 0x85, 0x01, // Report ID (0x1) 24 0x09, 0x21, // Usage (0x21) 25 0xa1, 0x00, // Collection (Physical) 26 0x05, 0x01, // Usage Page (Generic Desktop) 27 0x09, 0x30, // Usage (0x30) 28 0x09, 0x31, // Usage (0x31) 29 0x75, 0x10, // Report Size (16) 30 0x95, 0x02, // Report Count (2) 31 0x15, 0x00, // Logical Minimum (0) 32 0x26, 0xe0, 0x2e, // Logical Maximum (12000) 33 0x35, 0x00, // Physical Minimum (0) 34 0x45, 0x0c, // Physical Maximum (12) 35 0x65, 0x13, // Unit (19) 36 0x55, 0x00, // Unit Exponent (0) 37 0xa4, // Push 38 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 39 0x05, 0x0d, // Usage Page (Digitizer) 40 0x09, 0x32, // Usage (0x32) 41 0x09, 0x44, // Usage (0x44) 42 0x09, 0x42, // Usage (0x42) 43 0x15, 0x00, // Logical Minimum (0) 44 0x25, 0x01, // Logical Maximum (1) 45 0x35, 0x00, // Physical Minimum (0) 46 0x45, 0x01, // Physical Maximum (1) 47 0x75, 0x01, // Report Size (1) 48 0x95, 0x03, // Report Count (3) 49 0x65, 0x00, // Unit (0) 50 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 51 0x95, 0x01, // Report Count (1) 52 0x75, 0x05, // Report Size (5) 53 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 54 0xc0, // End Collection 55 0x85, 0x02, // Report ID (0x2) 56 0x09, 0x20, // Usage (0x20) 57 0xa1, 0x00, // Collection (Physical) 58 0xb4, // Pop 59 0xa4, // Push 60 0x09, 0x30, // Usage (0x30) 61 0x09, 0x31, // Usage (0x31) 62 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 63 0x05, 0x0d, // Usage Page (Digitizer) 64 0x09, 0x32, // Usage (0x32) 65 0x15, 0x00, // Logical Minimum (0) 66 0x25, 0x01, // Logical Maximum (1) 67 0x35, 0x00, // Physical Minimum (0) 68 0x45, 0x01, // Physical Maximum (1) 69 0x65, 0x00, // Unit (0) 70 0x75, 0x01, // Report Size (1) 71 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 72 0x05, 0x09, // Usage Page (Button) 73 0x19, 0x00, // Usage Minimum (0) 74 0x29, 0x10, // Usage Maximum (16) 75 0x25, 0x10, // Logical Maximum (16) 76 0x75, 0x05, // Report Size (5) 77 0x81, 0x40, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|Null|BitF) 78 0x75, 0x02, // Report Size (2) 79 0x81, 0x01, // Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 80 0xc0, // End Collection 81 0x85, 0x03, // Report ID (0x3) 82 0x05, 0x0d, // Usage Page (Digitizer) 83 0x09, 0x20, // Usage (0x20) 84 0xa1, 0x00, // Collection (Physical) 85 0xb4, // Pop 86 0x09, 0x30, // Usage (0x30) 87 0x09, 0x31, // Usage (0x31) 88 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 89 0x05, 0x0d, // Usage Page (Digitizer) 90 0x09, 0x32, // Usage (0x32) 91 0x09, 0x44, // Usage (0x44) 92 0x75, 0x01, // Report Size (1) 93 0x15, 0x00, // Logical Minimum (0) 94 0x25, 0x01, // Logical Maximum (1) 95 0x35, 0x00, // Physical Minimum (0) 96 0x45, 0x01, // Physical Maximum (1) 97 0x65, 0x00, // Unit (0) 98 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 99 0x95, 0x06, // Report Count (6) 100 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 101 0x09, 0x30, // Usage (0x30) 102 0x15, 0x00, // Logical Minimum (0) 103 0x25, 0x7f, // Logical Maximum (127) 104 0x35, 0x00, // Physical Minimum (0) 105 0x45, 0x2d, // Physical Maximum (45) 106 0x67, 0x11, 0xe1, // Unit (57617) 107 0x00, 0x00, // Default 108 0x55, 0x04, // Unit Exponent (4) 109 0x75, 0x08, // Report Size (8) 110 0x95, 0x01, // Report Count (1) 111 0x81, 0x12, // Input (Dat|Arr|Rel|NoWrp|NoLin|Prf|NoNull|BitF) 112 0xc0, // End Collection 113 0xc0 // End Collection 114 }; 115 116 // Keyboard descriptor from HID descriptor tool 117 // http://www.usb.org/developers/hidpage/dt2_4.zip 118 const uint8_t kKeyboard[] = { 119 0x05, 0x01, // Usage Page (Generic Desktop) 120 0x09, 0x06, // Usage (0x6) 121 0xa1, 0x01, // Collection (Application) 122 0x05, 0x07, // Usage Page (Keyboard) 123 0x19, 0xe0, // Usage Minimum (224) 124 0x29, 0xe7, // Usage Maximum (231) 125 0x15, 0x00, // Logical Minimum (0) 126 0x25, 0x01, // Logical Maximum (1) 127 0x75, 0x01, // Report Size (1) 128 0x95, 0x08, // Report Count (8) 129 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 130 0x95, 0x01, // Report Count (1) 131 0x75, 0x08, // Report Size (8) 132 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 133 0x95, 0x05, // Report Count (5) 134 0x75, 0x01, // Report Size (1) 135 0x05, 0x08, // Usage Page (Led) 136 0x19, 0x01, // Usage Minimum (1) 137 0x29, 0x05, // Usage Maximum (5) 138 0x91, 0x02, // Output (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 139 0x95, 0x01, // Report Count (1) 140 0x75, 0x03, // Report Size (3) 141 0x91, 0x03, // Output (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 142 0x95, 0x06, // Report Count (6) 143 0x75, 0x08, // Report Size (8) 144 0x15, 0x00, // Logical Minimum (0) 145 0x25, 0x65, // Logical Maximum (101) 146 0x05, 0x07, // Usage Page (Keyboard) 147 0x19, 0x00, // Usage Minimum (0) 148 0x29, 0x65, // Usage Maximum (101) 149 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 150 0xc0 // End Collection 151 }; 152 153 // Monitor descriptor from HID descriptor tool 154 // http://www.usb.org/developers/hidpage/dt2_4.zip 155 const uint8_t kMonitor[] = { 156 0x05, 0x80, // Usage Page (Monitor 0) 157 0x09, 0x01, // Usage (0x1) 158 0xa1, 0x01, // Collection (Application) 159 0x85, 0x01, // Report ID (0x1) 160 0x15, 0x00, // Logical Minimum (0) 161 0x26, 0xff, 0x00, // Logical Maximum (255) 162 0x75, 0x08, // Report Size (8) 163 0x95, 0x80, // Report Count (128) 164 0x09, 0x02, // Usage (0x2) 165 0xb2, 0x02, 0x01, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|Buff) 166 0x85, 0x02, // Report ID (0x2) 167 0x95, 0xf3, // Report Count (243) 168 0x09, 0x03, // Usage (0x3) 169 0xb2, 0x02, 0x01, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|Buff) 170 0x85, 0x03, // Report ID (0x3) 171 0x05, 0x82, // Usage Page (Monitor 2) 172 0x95, 0x01, // Report Count (1) 173 0x75, 0x10, // Report Size (16) 174 0x26, 0xc8, 0x00, // Logical Maximum (200) 175 0x09, 0x10, // Usage (0x10) 176 0xb1, 0x02, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 177 0x85, 0x04, // Report ID (0x4) 178 0x25, 0x64, // Logical Maximum (100) 179 0x09, 0x12, // Usage (0x12) 180 0xb1, 0x02, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 181 0x95, 0x06, // Report Count (6) 182 0x26, 0xff, 0x00, // Logical Maximum (255) 183 0x09, 0x16, // Usage (0x16) 184 0x09, 0x18, // Usage (0x18) 185 0x09, 0x1a, // Usage (0x1A) 186 0x09, 0x6c, // Usage (0x6C) 187 0x09, 0x6e, // Usage (0x6E) 188 0x09, 0x70, // Usage (0x70) 189 0xb1, 0x02, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 190 0x85, 0x05, // Report ID (0x5) 191 0x25, 0x7f, // Logical Maximum (127) 192 0x09, 0x20, // Usage (0x20) 193 0x09, 0x22, // Usage (0x22) 194 0x09, 0x30, // Usage (0x30) 195 0x09, 0x32, // Usage (0x32) 196 0x09, 0x42, // Usage (0x42) 197 0x09, 0x44, // Usage (0x44) 198 0xb1, 0x02, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 199 0xc0 // End Collection 200 }; 201 202 // Mouse descriptor from HID descriptor tool 203 // http://www.usb.org/developers/hidpage/dt2_4.zip 204 const uint8_t kMouse[] = { 205 0x05, 0x01, // Usage Page (Generic Desktop) 206 0x09, 0x02, // Usage (0x2) 207 0xa1, 0x01, // Collection (Application) 208 0x09, 0x01, // Usage (0x1) 209 0xa1, 0x00, // Collection (Physical) 210 0x05, 0x09, // Usage Page (Button) 211 0x19, 0x01, // Usage Minimum (1) 212 0x29, 0x03, // Usage Maximum (3) 213 0x15, 0x00, // Logical Minimum (0) 214 0x25, 0x01, // Logical Maximum (1) 215 0x95, 0x03, // Report Count (3) 216 0x75, 0x01, // Report Size (1) 217 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 218 0x95, 0x01, // Report Count (1) 219 0x75, 0x05, // Report Size (5) 220 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 221 0x05, 0x01, // Usage Page (Generic Desktop) 222 0x09, 0x30, // Usage (0x30) 223 0x09, 0x31, // Usage (0x31) 224 0x15, 0x81, // Logical Minimum (129) 225 0x25, 0x7f, // Logical Maximum (127) 226 0x75, 0x08, // Report Size (8) 227 0x95, 0x02, // Report Count (2) 228 0x81, 0x06, // Input (Dat|Arr|Abs|NoWrp|Lin|Prf|NoNull|BitF) 229 0xc0, // End Collection 230 0xc0 // End Collection 231 }; 232 233 // Logitech Unifying receiver descriptor 234 const uint8_t kLogitechUnifyingReceiver[] = { 235 0x06, 0x00, 0xFF, // Usage Page (Vendor) 236 0x09, 0x01, // Usage (0x1) 237 0xA1, 0x01, // Collection (Application) 238 0x85, 0x10, // Report ID (0x10) 239 0x75, 0x08, // Report Size (8) 240 0x95, 0x06, // Report Count (6) 241 0x15, 0x00, // Logical Minimum (0) 242 0x26, 0xFF, 0x00, // Logical Maximum (255) 243 0x09, 0x01, // Usage (0x1) 244 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 245 0x09, 0x01, // Usage (0x1) 246 0x91, 0x00, // Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 247 0xC0, // End Collection 248 0x06, 0x00, 0xFF, // Usage Page (Vendor) 249 0x09, 0x02, // Usage (0x2) 250 0xA1, 0x01, // Collection (Application) 251 0x85, 0x11, // Report ID (0x11) 252 0x75, 0x08, // Report Size (8) 253 0x95, 0x13, // Report Count (19) 254 0x15, 0x00, // Logical Minimum (0) 255 0x26, 0xFF, 0x00, // Logical Maximum (255) 256 0x09, 0x02, // Usage (0x2) 257 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 258 0x09, 0x02, // Usage (0x2) 259 0x91, 0x00, // Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 260 0xC0, // End Collection 261 0x06, 0x00, 0xFF, // Usage Page (Vendor) 262 0x09, 0x04, // Usage (0x4) 263 0xA1, 0x01, // Collection (Application) 264 0x85, 0x20, // Report ID (0x20) 265 0x75, 0x08, // Report Size (8) 266 0x95, 0x0E, // Report Count (14) 267 0x15, 0x00, // Logical Minimum (0) 268 0x26, 0xFF, 0x00, // Logical Maximum (255) 269 0x09, 0x41, // Usage (0x41) 270 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 271 0x09, 0x41, // Usage (0x41) 272 0x91, 0x00, // Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 273 0x85, 0x21, // Report ID (0x21) 274 0x95, 0x1F, // Report Count (31) 275 0x15, 0x00, // Logical Minimum (0) 276 0x26, 0xFF, 0x00, // Logical Maximum (255) 277 0x09, 0x42, // Usage (0x42) 278 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 279 0x09, 0x42, // Usage (0x42) 280 0x91, 0x00, // Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 281 0xC0 // End Collection 282 }; 283 284 } // namespace 285 286 class HidReportDescriptorTest : public testing::Test { 287 288 protected: 289 virtual void SetUp() OVERRIDE { descriptor_ = NULL; } 290 291 virtual void TearDown() OVERRIDE { 292 if (descriptor_) { 293 delete descriptor_; 294 } 295 } 296 297 public: 298 void ValidateDetails( 299 const std::vector<HidCollectionInfo>& expected_collections, 300 const bool expected_has_report_id, 301 const uint16_t expected_max_input_report_size, 302 const uint16_t expected_max_output_report_size, 303 const uint16_t expected_max_feature_report_size, 304 const uint8_t* bytes, 305 size_t size) { 306 descriptor_ = new HidReportDescriptor(bytes, size); 307 308 std::vector<HidCollectionInfo> actual_collections; 309 bool actual_has_report_id; 310 uint16_t actual_max_input_report_size; 311 uint16_t actual_max_output_report_size; 312 uint16_t actual_max_feature_report_size; 313 descriptor_->GetDetails(&actual_collections, 314 &actual_has_report_id, 315 &actual_max_input_report_size, 316 &actual_max_output_report_size, 317 &actual_max_feature_report_size); 318 319 ASSERT_EQ(expected_collections.size(), actual_collections.size()); 320 321 std::vector<HidCollectionInfo>::const_iterator actual_collections_iter = 322 actual_collections.begin(); 323 std::vector<HidCollectionInfo>::const_iterator expected_collections_iter = 324 expected_collections.begin(); 325 326 while (expected_collections_iter != expected_collections.end() && 327 actual_collections_iter != actual_collections.end()) { 328 HidCollectionInfo expected_collection = *expected_collections_iter; 329 HidCollectionInfo actual_collection = *actual_collections_iter; 330 331 ASSERT_EQ(expected_collection.usage.usage_page, 332 actual_collection.usage.usage_page); 333 ASSERT_EQ(expected_collection.usage.usage, actual_collection.usage.usage); 334 ASSERT_THAT(actual_collection.report_ids, 335 ContainerEq(expected_collection.report_ids)); 336 337 expected_collections_iter++; 338 actual_collections_iter++; 339 } 340 341 ASSERT_EQ(expected_has_report_id, actual_has_report_id); 342 ASSERT_EQ(expected_max_input_report_size, actual_max_input_report_size); 343 ASSERT_EQ(expected_max_output_report_size, actual_max_output_report_size); 344 ASSERT_EQ(expected_max_feature_report_size, actual_max_feature_report_size); 345 } 346 347 private: 348 HidReportDescriptor* descriptor_; 349 }; 350 351 TEST_F(HidReportDescriptorTest, ValidateDetails_Digitizer) { 352 HidCollectionInfo digitizer; 353 digitizer.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageDigitizer); 354 digitizer.report_ids.insert(1); 355 digitizer.report_ids.insert(2); 356 digitizer.report_ids.insert(3); 357 HidCollectionInfo expected[] = {digitizer}; 358 ValidateDetails(std::vector<HidCollectionInfo>( 359 expected, expected + ARRAYSIZE_UNSAFE(expected)), 360 true, 361 6, 362 0, 363 0, 364 kDigitizer, 365 sizeof(kDigitizer)); 366 } 367 368 TEST_F(HidReportDescriptorTest, ValidateDetails_Keyboard) { 369 HidCollectionInfo keyboard; 370 keyboard.usage = HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop); 371 HidCollectionInfo expected[] = {keyboard}; 372 ValidateDetails(std::vector<HidCollectionInfo>( 373 expected, expected + ARRAYSIZE_UNSAFE(expected)), 374 false, 375 8, 376 1, 377 0, 378 kKeyboard, 379 sizeof(kKeyboard)); 380 } 381 382 TEST_F(HidReportDescriptorTest, ValidateDetails_Monitor) { 383 HidCollectionInfo monitor; 384 monitor.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageMonitor0); 385 monitor.report_ids.insert(1); 386 monitor.report_ids.insert(2); 387 monitor.report_ids.insert(3); 388 monitor.report_ids.insert(4); 389 monitor.report_ids.insert(5); 390 HidCollectionInfo expected[] = {monitor}; 391 ValidateDetails(std::vector<HidCollectionInfo>( 392 expected, expected + ARRAYSIZE_UNSAFE(expected)), 393 true, 394 0, 395 0, 396 243, 397 kMonitor, 398 sizeof(kMonitor)); 399 } 400 401 TEST_F(HidReportDescriptorTest, ValidateDetails_Mouse) { 402 HidCollectionInfo mouse; 403 mouse.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop); 404 HidCollectionInfo expected[] = {mouse}; 405 ValidateDetails(std::vector<HidCollectionInfo>( 406 expected, expected + ARRAYSIZE_UNSAFE(expected)), 407 false, 408 3, 409 0, 410 0, 411 kMouse, 412 sizeof(kMouse)); 413 } 414 415 TEST_F(HidReportDescriptorTest, ValidateDetails_LogitechUnifyingReceiver) { 416 HidCollectionInfo hidpp_short; 417 hidpp_short.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageVendor); 418 hidpp_short.report_ids.insert(0x10); 419 HidCollectionInfo hidpp_long; 420 hidpp_long.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageVendor); 421 hidpp_long.report_ids.insert(0x11); 422 HidCollectionInfo hidpp_dj; 423 hidpp_dj.usage = HidUsageAndPage(0x04, HidUsageAndPage::kPageVendor); 424 hidpp_dj.report_ids.insert(0x20); 425 hidpp_dj.report_ids.insert(0x21); 426 427 HidCollectionInfo expected[] = {hidpp_short, hidpp_long, hidpp_dj}; 428 ValidateDetails(std::vector<HidCollectionInfo>( 429 expected, expected + ARRAYSIZE_UNSAFE(expected)), 430 true, 431 31, 432 31, 433 0, 434 kLogitechUnifyingReceiver, 435 sizeof(kLogitechUnifyingReceiver)); 436 } 437 438 } // namespace device 439