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 |