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 descriptor_ = new HidReportDescriptor(bytes, size); |
| 62 |
| 63 std::stringstream parsed_actual; |
| 64 parsed_actual << *descriptor_; |
| 65 |
| 66 std::cout << "HID report descriptor:" << std::endl; |
| 67 std::cout << *descriptor_; |
| 68 |
| 69 ASSERT_EQ(parsed_expected, parsed_actual.str()); |
| 70 } |
| 71 |
| 72 void GetTopLevelCollections(const std::vector<HidUsageAndPage>& tlcs_expected, |
| 73 const uint8_t* bytes, |
| 74 size_t size) { |
| 75 descriptor_ = new HidReportDescriptor(bytes, size); |
| 76 |
| 77 std::vector<HidUsageAndPage> tlcs_actual = |
| 78 descriptor_->topLevelCollections(); |
| 79 |
| 80 std::cout << "HID top-level collections:" << std::endl; |
| 81 for (std::vector<HidUsageAndPage>::const_iterator tlcs_iter = |
| 82 tlcs_actual.begin(); |
| 83 tlcs_iter != tlcs_actual.end(); |
| 84 ++tlcs_iter) { |
| 85 std::cout << *tlcs_iter << std::endl; |
| 86 } |
| 87 |
| 88 ASSERT_THAT(tlcs_actual, ContainerEq(tlcs_expected)); |
| 89 } |
| 90 |
| 91 private: |
| 92 HidReportDescriptor* descriptor_; |
| 93 }; |
| 94 |
| 95 TEST_F(HidReportDescriptorTest, ParseDescriptor_Keyboard) { |
| 96 const char parsed_expected[] = { |
| 97 "Usage Page (Generic Desktop)\n" |
| 98 "Usage (0x6)\n" |
| 99 "Collection (Physical)\n" |
| 100 " Usage Page (Keyboard)\n" |
| 101 " Usage Minimum (0xE0)\n" |
| 102 " Usage Maximum (0xE7)\n" |
| 103 " Logical Minimum (0)\n" |
| 104 " Logical Maximum (1)\n" |
| 105 " Report Size (1)\n" |
| 106 " Report Count (8)\n" |
| 107 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 108 " Report Count (1)\n" |
| 109 " Report Size (8)\n" |
| 110 " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 111 " Report Count (5)\n" |
| 112 " Report Size (1)\n" |
| 113 " Usage Page (Led)\n" |
| 114 " Usage Minimum (0x1)\n" |
| 115 " Usage Maximum (0x5)\n" |
| 116 " Output (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 117 " Report Count (1)\n" |
| 118 " Report Size (3)\n" |
| 119 " Output (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 120 " Report Count (6)\n" |
| 121 " Report Size (8)\n" |
| 122 " Logical Minimum (0)\n" |
| 123 " Logical Maximum (101)\n" |
| 124 " Usage Page (Keyboard)\n" |
| 125 " Usage Minimum (0x0)\n" |
| 126 " Usage Maximum (0x65)\n" |
| 127 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 128 "End Collection\n"}; |
| 129 |
| 130 ParseDescriptor(std::string(parsed_expected), kKeyboard, sizeof(kKeyboard)); |
| 131 } |
| 132 |
| 133 TEST_F(HidReportDescriptorTest, TopLevelCollections_Keyboard) { |
| 134 HidUsageAndPage tlcs_expected[] = { |
| 135 HidUsageAndPage(HidUsageAndPage::kPageGenericDesktop, 0x06)}; |
| 136 |
| 137 GetTopLevelCollections( |
| 138 std::vector<HidUsageAndPage>( |
| 139 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| 140 kKeyboard, |
| 141 sizeof(kKeyboard)); |
| 142 } |
| 143 |
| 144 TEST_F(HidReportDescriptorTest, ParseDescriptor_Mouse) { |
| 145 const char parsed_expected[] = { |
| 146 "Usage Page (Generic Desktop)\n" |
| 147 "Usage (0x2)\n" |
| 148 "Collection (Physical)\n" |
| 149 " Usage (0x1)\n" |
| 150 " Collection (Physical)\n" |
| 151 " Usage Page (Button)\n" |
| 152 " Usage Minimum (0x1)\n" |
| 153 " Usage Maximum (0x3)\n" |
| 154 " Logical Minimum (0)\n" |
| 155 " Logical Maximum (1)\n" |
| 156 " Report Count (3)\n" |
| 157 " Report Size (1)\n" |
| 158 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 159 " Report Count (1)\n" |
| 160 " Report Size (5)\n" |
| 161 " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 162 " Usage Page (Generic Desktop)\n" |
| 163 " Usage (0x30)\n" |
| 164 " Usage (0x31)\n" |
| 165 " Logical Minimum (129)\n" |
| 166 " Logical Maximum (127)\n" |
| 167 " Report Size (8)\n" |
| 168 " Report Count (2)\n" |
| 169 " Input (Dat|Arr|Abs|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 170 " End Collection\n" |
| 171 "End Collection\n"}; |
| 172 |
| 173 ParseDescriptor(std::string(parsed_expected), kMouse, sizeof(kMouse)); |
| 174 } |
| 175 |
| 176 TEST_F(HidReportDescriptorTest, TopLevelCollections_Mouse) { |
| 177 HidUsageAndPage tlcs_expected[] = { |
| 178 HidUsageAndPage(HidUsageAndPage::kPageGenericDesktop, 0x02)}; |
| 179 |
| 180 GetTopLevelCollections( |
| 181 std::vector<HidUsageAndPage>( |
| 182 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| 183 kMouse, |
| 184 sizeof(kMouse)); |
| 185 } |
| 186 |
| 187 TEST_F(HidReportDescriptorTest, ParseDescriptor_LogitechUnifyingReceiver) { |
| 188 const char parsed_expected[] = { |
| 189 "Usage Page (Vendor)\n" |
| 190 "Usage (0x1)\n" |
| 191 "Collection (Physical)\n" |
| 192 " Report ID (0x10)\n" |
| 193 " Report Size (8)\n" |
| 194 " Report Count (6)\n" |
| 195 " Logical Minimum (0)\n" |
| 196 " Logical Maximum (255)\n" |
| 197 " Usage (0x1)\n" |
| 198 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 199 " Usage (0x1)\n" |
| 200 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 201 "End Collection\n" |
| 202 "Usage Page (Vendor)\n" |
| 203 "Usage (0x2)\n" |
| 204 "Collection (Physical)\n" |
| 205 " Report ID (0x11)\n" |
| 206 " Report Size (8)\n" |
| 207 " Report Count (19)\n" |
| 208 " Logical Minimum (0)\n" |
| 209 " Logical Maximum (255)\n" |
| 210 " Usage (0x2)\n" |
| 211 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 212 " Usage (0x2)\n" |
| 213 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 214 "End Collection\n" |
| 215 "Usage Page (Vendor)\n" |
| 216 "Usage (0x4)\n" |
| 217 "Collection (Physical)\n" |
| 218 " Report ID (0x20)\n" |
| 219 " Report Size (8)\n" |
| 220 " Report Count (14)\n" |
| 221 " Logical Minimum (0)\n" |
| 222 " Logical Maximum (255)\n" |
| 223 " Usage (0x41)\n" |
| 224 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 225 " Usage (0x41)\n" |
| 226 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 227 " Report ID (0x21)\n" |
| 228 " Report Count (31)\n" |
| 229 " Logical Minimum (0)\n" |
| 230 " Logical Maximum (255)\n" |
| 231 " Usage (0x42)\n" |
| 232 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 233 " Usage (0x42)\n" |
| 234 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| 235 "End Collection\n"}; |
| 236 |
| 237 ParseDescriptor(std::string(parsed_expected), |
| 238 kLogitechUnifyingReceiver, |
| 239 sizeof(kLogitechUnifyingReceiver)); |
| 240 } |
| 241 |
| 242 TEST_F(HidReportDescriptorTest, TopLevelCollections_LogitechUnifyingReceiver) { |
| 243 HidUsageAndPage tlcs_expected[] = { |
| 244 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x01), |
| 245 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x02), |
| 246 HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x04), |
| 247 }; |
| 248 |
| 249 GetTopLevelCollections( |
| 250 std::vector<HidUsageAndPage>( |
| 251 tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| 252 kLogitechUnifyingReceiver, |
| 253 sizeof(kLogitechUnifyingReceiver)); |
| 254 } |
| 255 |
| 256 } // namespace device |
OLD | NEW |