Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: trunk/src/device/hid/hid_report_descriptor_unittest.cc

Issue 364213005: Revert 281282 "Revert 281133 "chrome.hid: enrich model with repo..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <sstream> 5 #include <sstream>
6 6
7 #include "device/hid/hid_report_descriptor.h" 7 #include "device/hid/hid_report_descriptor.h"
8 #include "testing/gmock/include/gmock/gmock.h" 8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
10 10
11 using namespace testing; 11 using namespace testing;
12 12
13 namespace device { 13 namespace device {
14 14
15 namespace { 15 namespace {
16 16
17 std::ostream& operator<<(std::ostream& os, 17 // Digitizer descriptor from HID descriptor tool
18 const HidUsageAndPage::Page& usage_page) { 18 // http://www.usb.org/developers/hidpage/dt2_4.zip
19 switch (usage_page) { 19 const uint8_t kDigitizer[] = {
20 case HidUsageAndPage::kPageUndefined: 20 0x05, 0x0d, // Usage Page (Digitizer)
21 os << "Undefined"; 21 0x09, 0x01, // Usage (0x1)
22 break; 22 0xa1, 0x01, // Collection (Application)
23 case HidUsageAndPage::kPageGenericDesktop: 23 0x85, 0x01, // Report ID (0x1)
24 os << "Generic Desktop"; 24 0x09, 0x21, // Usage (0x21)
25 break; 25 0xa1, 0x00, // Collection (Physical)
26 case HidUsageAndPage::kPageSimulation: 26 0x05, 0x01, // Usage Page (Generic Desktop)
27 os << "Simulation"; 27 0x09, 0x30, // Usage (0x30)
28 break; 28 0x09, 0x31, // Usage (0x31)
29 case HidUsageAndPage::kPageVirtualReality: 29 0x75, 0x10, // Report Size (16)
30 os << "Virtual Reality"; 30 0x95, 0x02, // Report Count (2)
31 break; 31 0x15, 0x00, // Logical Minimum (0)
32 case HidUsageAndPage::kPageSport: 32 0x26, 0xe0, 0x2e, // Logical Maximum (12000)
33 os << "Sport"; 33 0x35, 0x00, // Physical Minimum (0)
34 break; 34 0x45, 0x0c, // Physical Maximum (12)
35 case HidUsageAndPage::kPageGame: 35 0x65, 0x13, // Unit (19)
36 os << "Game"; 36 0x55, 0x00, // Unit Exponent (0)
37 break; 37 0xa4, // Push
38 case HidUsageAndPage::kPageKeyboard: 38 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
39 os << "Keyboard"; 39 0x05, 0x0d, // Usage Page (Digitizer)
40 break; 40 0x09, 0x32, // Usage (0x32)
41 case HidUsageAndPage::kPageLed: 41 0x09, 0x44, // Usage (0x44)
42 os << "Led"; 42 0x09, 0x42, // Usage (0x42)
43 break; 43 0x15, 0x00, // Logical Minimum (0)
44 case HidUsageAndPage::kPageButton: 44 0x25, 0x01, // Logical Maximum (1)
45 os << "Button"; 45 0x35, 0x00, // Physical Minimum (0)
46 break; 46 0x45, 0x01, // Physical Maximum (1)
47 case HidUsageAndPage::kPageOrdinal: 47 0x75, 0x01, // Report Size (1)
48 os << "Ordinal"; 48 0x95, 0x03, // Report Count (3)
49 break; 49 0x65, 0x00, // Unit (0)
50 case HidUsageAndPage::kPageTelephony: 50 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
51 os << "Telephony"; 51 0x95, 0x01, // Report Count (1)
52 break; 52 0x75, 0x05, // Report Size (5)
53 case HidUsageAndPage::kPageConsumer: 53 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
54 os << "Consumer"; 54 0xc0, // End Collection
55 break; 55 0x85, 0x02, // Report ID (0x2)
56 case HidUsageAndPage::kPageDigitizer: 56 0x09, 0x20, // Usage (0x20)
57 os << "Digitizer"; 57 0xa1, 0x00, // Collection (Physical)
58 break; 58 0xb4, // Pop
59 case HidUsageAndPage::kPagePidPage: 59 0xa4, // Push
60 os << "Pid Page"; 60 0x09, 0x30, // Usage (0x30)
61 break; 61 0x09, 0x31, // Usage (0x31)
62 case HidUsageAndPage::kPageUnicode: 62 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
63 os << "Unicode"; 63 0x05, 0x0d, // Usage Page (Digitizer)
64 break; 64 0x09, 0x32, // Usage (0x32)
65 case HidUsageAndPage::kPageAlphanumericDisplay: 65 0x15, 0x00, // Logical Minimum (0)
66 os << "Alphanumeric Display"; 66 0x25, 0x01, // Logical Maximum (1)
67 break; 67 0x35, 0x00, // Physical Minimum (0)
68 case HidUsageAndPage::kPageMedicalInstruments: 68 0x45, 0x01, // Physical Maximum (1)
69 os << "Medical Instruments"; 69 0x65, 0x00, // Unit (0)
70 break; 70 0x75, 0x01, // Report Size (1)
71 case HidUsageAndPage::kPageMonitor0: 71 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
72 os << "Monitor 0"; 72 0x05, 0x09, // Usage Page (Button)
73 break; 73 0x19, 0x00, // Usage Minimum (0)
74 case HidUsageAndPage::kPageMonitor1: 74 0x29, 0x10, // Usage Maximum (16)
75 os << "Monitor 1"; 75 0x25, 0x10, // Logical Maximum (16)
76 break; 76 0x75, 0x05, // Report Size (5)
77 case HidUsageAndPage::kPageMonitor2: 77 0x81, 0x40, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|Null|BitF)
78 os << "Monitor 2"; 78 0x75, 0x02, // Report Size (2)
79 break; 79 0x81, 0x01, // Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
80 case HidUsageAndPage::kPageMonitor3: 80 0xc0, // End Collection
81 os << "Monitor 3"; 81 0x85, 0x03, // Report ID (0x3)
82 break; 82 0x05, 0x0d, // Usage Page (Digitizer)
83 case HidUsageAndPage::kPagePower0: 83 0x09, 0x20, // Usage (0x20)
84 os << "Power 0"; 84 0xa1, 0x00, // Collection (Physical)
85 break; 85 0xb4, // Pop
86 case HidUsageAndPage::kPagePower1: 86 0x09, 0x30, // Usage (0x30)
87 os << "Power 1"; 87 0x09, 0x31, // Usage (0x31)
88 break; 88 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
89 case HidUsageAndPage::kPagePower2: 89 0x05, 0x0d, // Usage Page (Digitizer)
90 os << "Power 2"; 90 0x09, 0x32, // Usage (0x32)
91 break; 91 0x09, 0x44, // Usage (0x44)
92 case HidUsageAndPage::kPagePower3: 92 0x75, 0x01, // Report Size (1)
93 os << "Power 3"; 93 0x15, 0x00, // Logical Minimum (0)
94 break; 94 0x25, 0x01, // Logical Maximum (1)
95 case HidUsageAndPage::kPageBarCodeScanner: 95 0x35, 0x00, // Physical Minimum (0)
96 os << "Bar Code Scanner"; 96 0x45, 0x01, // Physical Maximum (1)
97 break; 97 0x65, 0x00, // Unit (0)
98 case HidUsageAndPage::kPageScale: 98 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
99 os << "Scale"; 99 0x95, 0x06, // Report Count (6)
100 break; 100 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
101 case HidUsageAndPage::kPageMagneticStripeReader: 101 0x09, 0x30, // Usage (0x30)
102 os << "Magnetic Stripe Reader"; 102 0x15, 0x00, // Logical Minimum (0)
103 break; 103 0x25, 0x7f, // Logical Maximum (127)
104 case HidUsageAndPage::kPageReservedPointOfSale: 104 0x35, 0x00, // Physical Minimum (0)
105 os << "Reserved Point Of Sale"; 105 0x45, 0x2d, // Physical Maximum (45)
106 break; 106 0x67, 0x11, 0xe1, // Unit (57617)
107 case HidUsageAndPage::kPageCameraControl: 107 0x00, 0x00, // Default
108 os << "Camera Control"; 108 0x55, 0x04, // Unit Exponent (4)
109 break; 109 0x75, 0x08, // Report Size (8)
110 case HidUsageAndPage::kPageArcade: 110 0x95, 0x01, // Report Count (1)
111 os << "Arcade"; 111 0x81, 0x12, // Input (Dat|Arr|Rel|NoWrp|NoLin|Prf|NoNull|BitF)
112 break; 112 0xc0, // End Collection
113 case HidUsageAndPage::kPageVendor: 113 0xc0 // End Collection
114 os << "Vendor"; 114 };
115 break; 115
116 case HidUsageAndPage::kPageMediaCenter: 116 // Keyboard descriptor from HID descriptor tool
117 os << "Media Center"; 117 // http://www.usb.org/developers/hidpage/dt2_4.zip
118 break;
119 default:
120 NOTREACHED();
121 break;
122 }
123 return os;
124 }
125
126 std::ostream& operator<<(std::ostream& os,
127 const HidUsageAndPage& usage_and_page) {
128 os << "Usage Page: " << usage_and_page.usage_page << ", Usage: "
129 << "0x" << std::hex << std::uppercase << usage_and_page.usage;
130 return os;
131 }
132
133 std::ostream& operator<<(std::ostream& os,
134 const HidReportDescriptorItem::Tag& tag) {
135 switch (tag) {
136 case HidReportDescriptorItem::kTagDefault:
137 os << "Default";
138 break;
139 case HidReportDescriptorItem::kTagInput:
140 os << "Input";
141 break;
142 case HidReportDescriptorItem::kTagOutput:
143 os << "Output";
144 break;
145 case HidReportDescriptorItem::kTagFeature:
146 os << "Feature";
147 break;
148 case HidReportDescriptorItem::kTagCollection:
149 os << "Collection";
150 break;
151 case HidReportDescriptorItem::kTagEndCollection:
152 os << "End Collection";
153 break;
154 case HidReportDescriptorItem::kTagUsagePage:
155 os << "Usage Page";
156 break;
157 case HidReportDescriptorItem::kTagLogicalMinimum:
158 os << "Logical Minimum";
159 break;
160 case HidReportDescriptorItem::kTagLogicalMaximum:
161 os << "Logical Maximum";
162 break;
163 case HidReportDescriptorItem::kTagPhysicalMinimum:
164 os << "Physical Minimum";
165 break;
166 case HidReportDescriptorItem::kTagPhysicalMaximum:
167 os << "Physical Maximum";
168 break;
169 case HidReportDescriptorItem::kTagUnitExponent:
170 os << "Unit Exponent";
171 break;
172 case HidReportDescriptorItem::kTagUnit:
173 os << "Unit";
174 break;
175 case HidReportDescriptorItem::kTagReportSize:
176 os << "Report Size";
177 break;
178 case HidReportDescriptorItem::kTagReportId:
179 os << "Report ID";
180 break;
181 case HidReportDescriptorItem::kTagReportCount:
182 os << "Report Count";
183 break;
184 case HidReportDescriptorItem::kTagPush:
185 os << "Push";
186 break;
187 case HidReportDescriptorItem::kTagPop:
188 os << "Pop";
189 break;
190 case HidReportDescriptorItem::kTagUsage:
191 os << "Usage";
192 break;
193 case HidReportDescriptorItem::kTagUsageMinimum:
194 os << "Usage Minimum";
195 break;
196 case HidReportDescriptorItem::kTagUsageMaximum:
197 os << "Usage Maximum";
198 break;
199 case HidReportDescriptorItem::kTagDesignatorIndex:
200 os << "Designator Index";
201 break;
202 case HidReportDescriptorItem::kTagDesignatorMinimum:
203 os << "Designator Minimum";
204 break;
205 case HidReportDescriptorItem::kTagDesignatorMaximum:
206 os << "Designator Maximum";
207 break;
208 case HidReportDescriptorItem::kTagStringIndex:
209 os << "String Index";
210 break;
211 case HidReportDescriptorItem::kTagStringMinimum:
212 os << "String Minimum";
213 break;
214 case HidReportDescriptorItem::kTagStringMaximum:
215 os << "String Maximum";
216 break;
217 case HidReportDescriptorItem::kTagDelimiter:
218 os << "Delimeter";
219 break;
220 case HidReportDescriptorItem::kTagLong:
221 os << "Long";
222 break;
223 default:
224 NOTREACHED();
225 break;
226 }
227
228 return os;
229 }
230
231 std::ostream& operator<<(std::ostream& os,
232 const HidReportDescriptorItem::ReportInfo& data) {
233 if (data.data_or_constant)
234 os << "Con";
235 else
236 os << "Dat";
237 if (data.array_or_variable)
238 os << "|Arr";
239 else
240 os << "|Var";
241 if (data.absolute_or_relative)
242 os << "|Abs";
243 else
244 os << "|Rel";
245 if (data.wrap)
246 os << "|Wrp";
247 else
248 os << "|NoWrp";
249 if (data.linear)
250 os << "|NoLin";
251 else
252 os << "|Lin";
253 if (data.preferred)
254 os << "|NoPrf";
255 else
256 os << "|Prf";
257 if (data.null)
258 os << "|Null";
259 else
260 os << "|NoNull";
261 if (data.bit_field_or_buffer)
262 os << "|Buff";
263 else
264 os << "|BitF";
265 return os;
266 }
267
268 std::ostream& operator<<(std::ostream& os,
269 const HidReportDescriptorItem::CollectionType& type) {
270 switch (type) {
271 case HidReportDescriptorItem::kCollectionTypePhysical:
272 os << "Physical";
273 break;
274 case HidReportDescriptorItem::kCollectionTypeApplication:
275 os << "Application";
276 break;
277 case HidReportDescriptorItem::kCollectionTypeLogical:
278 os << "Logical";
279 break;
280 case HidReportDescriptorItem::kCollectionTypeReport:
281 os << "Report";
282 break;
283 case HidReportDescriptorItem::kCollectionTypeNamedArray:
284 os << "Named Array";
285 break;
286 case HidReportDescriptorItem::kCollectionTypeUsageSwitch:
287 os << "Usage Switch";
288 break;
289 case HidReportDescriptorItem::kCollectionTypeUsageModifier:
290 os << "Usage Modifier";
291 break;
292 case HidReportDescriptorItem::kCollectionTypeReserved:
293 os << "Reserved";
294 break;
295 case HidReportDescriptorItem::kCollectionTypeVendor:
296 os << "Vendor";
297 break;
298 default:
299 NOTREACHED();
300 break;
301 }
302 return os;
303 }
304
305 std::ostream& operator<<(std::ostream& os,
306 const HidReportDescriptorItem& item) {
307 HidReportDescriptorItem::Tag item_tag = item.tag();
308 uint32_t data = item.GetShortData();
309
310 std::ostringstream sstr;
311 sstr << item_tag;
312 sstr << " (";
313
314 long pos = sstr.tellp();
315 switch (item_tag) {
316 case HidReportDescriptorItem::kTagDefault:
317 case HidReportDescriptorItem::kTagEndCollection:
318 case HidReportDescriptorItem::kTagPush:
319 case HidReportDescriptorItem::kTagPop:
320 case HidReportDescriptorItem::kTagLong:
321 break;
322
323 case HidReportDescriptorItem::kTagCollection:
324 sstr << HidReportDescriptorItem::GetCollectionTypeFromValue(data);
325 break;
326
327 case HidReportDescriptorItem::kTagInput:
328 case HidReportDescriptorItem::kTagOutput:
329 case HidReportDescriptorItem::kTagFeature:
330 sstr << (HidReportDescriptorItem::ReportInfo&)data;
331 break;
332
333 case HidReportDescriptorItem::kTagUsagePage:
334 sstr << (HidUsageAndPage::Page)data;
335 break;
336
337 case HidReportDescriptorItem::kTagUsage:
338 case HidReportDescriptorItem::kTagReportId:
339 sstr << "0x" << std::hex << std::uppercase << data;
340 break;
341
342 default:
343 sstr << data;
344 break;
345 }
346 if (pos == sstr.tellp()) {
347 std::string str = sstr.str();
348 str.erase(str.end() - 2, str.end());
349 os << str;
350 } else {
351 os << sstr.str() << ")";
352 }
353
354 return os;
355 }
356
357 const char kIndentStep[] = " ";
358
359 std::ostream& operator<<(std::ostream& os,
360 const HidReportDescriptor& descriptor) {
361 for (std::vector<linked_ptr<HidReportDescriptorItem> >::const_iterator
362 items_iter = descriptor.items().begin();
363 items_iter != descriptor.items().end();
364 ++items_iter) {
365 linked_ptr<HidReportDescriptorItem> item = *items_iter;
366 size_t indentLevel = item->GetDepth();
367 for (size_t i = 0; i < indentLevel; i++)
368 os << kIndentStep;
369 os << *item.get() << std::endl;
370 }
371 return os;
372 }
373
374 // See 'E.6 Report Descriptor (Keyboard)'
375 // in HID specifications (v1.11)
376 const uint8_t kKeyboard[] = { 118 const uint8_t kKeyboard[] = {
377 0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0, 0x29, 119 0x05, 0x01, // Usage Page (Generic Desktop)
378 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 120 0x09, 0x06, // Usage (0x6)
379 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05, 0x75, 0x01, 0x05, 121 0xa1, 0x01, // Collection (Application)
380 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, 122 0x05, 0x07, // Usage Page (Keyboard)
381 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 123 0x19, 0xe0, // Usage Minimum (224)
382 0x07, 0x19, 0x00, 0x29, 0x65, 0x81, 0x00, 0xC0}; 124 0x29, 0xe7, // Usage Maximum (231)
383 125 0x15, 0x00, // Logical Minimum (0)
384 // See 'E.10 Report Descriptor (Mouse)' 126 0x25, 0x01, // Logical Maximum (1)
385 // in HID specifications (v1.11) 127 0x75, 0x01, // Report Size (1)
386 const uint8_t kMouse[] = {0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 128 0x95, 0x08, // Report Count (8)
387 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 129 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
388 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, 130 0x95, 0x01, // Report Count (1)
389 0x01, 0x75, 0x05, 0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 131 0x75, 0x08, // Report Size (8)
390 0x09, 0x31, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, 132 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
391 0x02, 0x81, 0x06, 0xC0, 0xC0}; 133 0x95, 0x05, // Report Count (5)
392 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
393 const uint8_t kLogitechUnifyingReceiver[] = { 234 const uint8_t kLogitechUnifyingReceiver[] = {
394 0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x75, 0x08, 235 0x06, 0x00, 0xFF, // Usage Page (Vendor)
395 0x95, 0x06, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x09, 0x01, 0x81, 0x00, 236 0x09, 0x01, // Usage (0x1)
396 0x09, 0x01, 0x91, 0x00, 0xC0, 0x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, 237 0xA1, 0x01, // Collection (Application)
397 0x01, 0x85, 0x11, 0x75, 0x08, 0x95, 0x13, 0x15, 0x00, 0x26, 0xFF, 238 0x85, 0x10, // Report ID (0x10)
398 0x00, 0x09, 0x02, 0x81, 0x00, 0x09, 0x02, 0x91, 0x00, 0xC0, 0x06, 239 0x75, 0x08, // Report Size (8)
399 0x00, 0xFF, 0x09, 0x04, 0xA1, 0x01, 0x85, 0x20, 0x75, 0x08, 0x95, 240 0x95, 0x06, // Report Count (6)
400 0x0E, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x09, 0x41, 0x81, 0x00, 0x09, 241 0x15, 0x00, // Logical Minimum (0)
401 0x41, 0x91, 0x00, 0x85, 0x21, 0x95, 0x1F, 0x15, 0x00, 0x26, 0xFF, 242 0x26, 0xFF, 0x00, // Logical Maximum (255)
402 0x00, 0x09, 0x42, 0x81, 0x00, 0x09, 0x42, 0x91, 0x00, 0xC0}; 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 };
403 283
404 } // namespace 284 } // namespace
405 285
406 class HidReportDescriptorTest : public testing::Test { 286 class HidReportDescriptorTest : public testing::Test {
407 287
408 protected: 288 protected:
409 virtual void SetUp() OVERRIDE { descriptor_ = NULL; } 289 virtual void SetUp() OVERRIDE { descriptor_ = NULL; }
410 290
411 virtual void TearDown() OVERRIDE { 291 virtual void TearDown() OVERRIDE {
412 if (descriptor_) { 292 if (descriptor_) {
413 delete descriptor_; 293 delete descriptor_;
414 } 294 }
415 } 295 }
416 296
417 public: 297 public:
418 void ParseDescriptor(const std::string& expected, 298 void ValidateDetails(
419 const uint8_t* bytes, 299 const std::vector<HidCollectionInfo>& expected_collections,
420 size_t size) { 300 const int expected_max_input_report_size,
301 const int expected_max_output_report_size,
302 const int expected_max_feature_report_size,
303 const uint8_t* bytes,
304 size_t size) {
421 descriptor_ = new HidReportDescriptor(bytes, size); 305 descriptor_ = new HidReportDescriptor(bytes, size);
422 306
423 std::stringstream actual; 307 std::vector<HidCollectionInfo> actual_collections;
424 actual << *descriptor_; 308 int actual_max_input_report_size;
309 int actual_max_output_report_size;
310 int actual_max_feature_report_size;
311 descriptor_->GetDetails(&actual_collections,
312 &actual_max_input_report_size,
313 &actual_max_output_report_size,
314 &actual_max_feature_report_size);
425 315
426 std::cout << "HID report descriptor:" << std::endl; 316 ASSERT_EQ(expected_collections.size(), actual_collections.size());
427 std::cout << actual.str();
428 317
429 // TODO(jracle@logitech.com): refactor string comparison in favor of 318 std::vector<HidCollectionInfo>::const_iterator actual_collections_iter =
430 // testing individual fields. 319 actual_collections.begin();
431 ASSERT_EQ(expected, actual.str()); 320 std::vector<HidCollectionInfo>::const_iterator expected_collections_iter =
432 } 321 expected_collections.begin();
433 322
434 void GetTopLevelCollections(const std::vector<HidUsageAndPage>& expected, 323 while (expected_collections_iter != expected_collections.end() &&
435 const uint8_t* bytes, 324 actual_collections_iter != actual_collections.end()) {
436 size_t size) { 325 HidCollectionInfo expected_collection = *expected_collections_iter;
437 descriptor_ = new HidReportDescriptor(bytes, size); 326 HidCollectionInfo actual_collection = *actual_collections_iter;
438 327
439 std::vector<HidUsageAndPage> actual; 328 ASSERT_EQ(expected_collection.usage.usage_page,
440 descriptor_->GetTopLevelCollections(&actual); 329 actual_collection.usage.usage_page);
330 ASSERT_EQ(expected_collection.usage.usage, actual_collection.usage.usage);
331 ASSERT_THAT(actual_collection.report_ids,
332 ContainerEq(expected_collection.report_ids));
441 333
442 std::cout << "HID top-level collections:" << std::endl; 334 expected_collections_iter++;
443 for (std::vector<HidUsageAndPage>::const_iterator iter = actual.begin(); 335 actual_collections_iter++;
444 iter != actual.end();
445 ++iter) {
446 std::cout << *iter << std::endl;
447 } 336 }
448 337
449 ASSERT_THAT(actual, ContainerEq(expected)); 338 ASSERT_EQ(expected_max_input_report_size, actual_max_input_report_size);
339 ASSERT_EQ(expected_max_output_report_size, actual_max_output_report_size);
340 ASSERT_EQ(expected_max_feature_report_size, actual_max_feature_report_size);
450 } 341 }
451 342
452 private: 343 private:
453 HidReportDescriptor* descriptor_; 344 HidReportDescriptor* descriptor_;
454 }; 345 };
455 346
456 TEST_F(HidReportDescriptorTest, ParseDescriptor_Keyboard) { 347 TEST_F(HidReportDescriptorTest, ValidateDetails_Digitizer) {
457 const char expected[] = { 348 HidCollectionInfo digitizer;
458 "Usage Page (Generic Desktop)\n" 349 digitizer.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageDigitizer);
459 "Usage (0x6)\n" 350 digitizer.report_ids.insert(1);
460 "Collection (Physical)\n" 351 digitizer.report_ids.insert(2);
461 " Usage Page (Keyboard)\n" 352 digitizer.report_ids.insert(3);
462 " Usage Minimum (224)\n" 353 HidCollectionInfo expected[] = {digitizer};
463 " Usage Maximum (231)\n" 354 ValidateDetails(std::vector<HidCollectionInfo>(
464 " Logical Minimum (0)\n" 355 expected, expected + ARRAYSIZE_UNSAFE(expected)),
465 " Logical Maximum (1)\n" 356 7,
466 " Report Size (1)\n" 357 0,
467 " Report Count (8)\n" 358 0,
468 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" 359 kDigitizer,
469 " Report Count (1)\n" 360 sizeof(kDigitizer));
470 " Report Size (8)\n"
471 " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
472 " Report Count (5)\n"
473 " Report Size (1)\n"
474 " Usage Page (Led)\n"
475 " Usage Minimum (1)\n"
476 " Usage Maximum (5)\n"
477 " Output (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
478 " Report Count (1)\n"
479 " Report Size (3)\n"
480 " Output (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
481 " Report Count (6)\n"
482 " Report Size (8)\n"
483 " Logical Minimum (0)\n"
484 " Logical Maximum (101)\n"
485 " Usage Page (Keyboard)\n"
486 " Usage Minimum (0)\n"
487 " Usage Maximum (101)\n"
488 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
489 "End Collection\n"};
490
491 ParseDescriptor(std::string(expected), kKeyboard, sizeof(kKeyboard));
492 } 361 }
493 362
494 TEST_F(HidReportDescriptorTest, TopLevelCollections_Keyboard) { 363 TEST_F(HidReportDescriptorTest, ValidateDetails_Keyboard) {
495 HidUsageAndPage expected[] = { 364 HidCollectionInfo keyboard;
496 HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop)}; 365 keyboard.usage = HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop);
497 366 HidCollectionInfo expected[] = {keyboard};
498 GetTopLevelCollections(std::vector<HidUsageAndPage>( 367 ValidateDetails(std::vector<HidCollectionInfo>(
499 expected, expected + ARRAYSIZE_UNSAFE(expected)), 368 expected, expected + ARRAYSIZE_UNSAFE(expected)),
500 kKeyboard, 369 8,
501 sizeof(kKeyboard)); 370 1,
371 0,
372 kKeyboard,
373 sizeof(kKeyboard));
502 } 374 }
503 375
504 TEST_F(HidReportDescriptorTest, ParseDescriptor_Mouse) { 376 TEST_F(HidReportDescriptorTest, ValidateDetails_Monitor) {
505 const char expected[] = { 377 HidCollectionInfo monitor;
506 "Usage Page (Generic Desktop)\n" 378 monitor.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageMonitor0);
507 "Usage (0x2)\n" 379 monitor.report_ids.insert(1);
508 "Collection (Physical)\n" 380 monitor.report_ids.insert(2);
509 " Usage (0x1)\n" 381 monitor.report_ids.insert(3);
510 " Collection (Physical)\n" 382 monitor.report_ids.insert(4);
511 " Usage Page (Button)\n" 383 monitor.report_ids.insert(5);
512 " Usage Minimum (1)\n" 384 HidCollectionInfo expected[] = {monitor};
513 " Usage Maximum (3)\n" 385 ValidateDetails(std::vector<HidCollectionInfo>(
514 " Logical Minimum (0)\n" 386 expected, expected + ARRAYSIZE_UNSAFE(expected)),
515 " Logical Maximum (1)\n" 387 0,
516 " Report Count (3)\n" 388 0,
517 " Report Size (1)\n" 389 244,
518 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" 390 kMonitor,
519 " Report Count (1)\n" 391 sizeof(kMonitor));
520 " Report Size (5)\n"
521 " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
522 " Usage Page (Generic Desktop)\n"
523 " Usage (0x30)\n"
524 " Usage (0x31)\n"
525 " Logical Minimum (129)\n"
526 " Logical Maximum (127)\n"
527 " Report Size (8)\n"
528 " Report Count (2)\n"
529 " Input (Dat|Arr|Abs|NoWrp|Lin|Prf|NoNull|BitF)\n"
530 " End Collection\n"
531 "End Collection\n"};
532
533 ParseDescriptor(std::string(expected), kMouse, sizeof(kMouse));
534 } 392 }
535 393
536 TEST_F(HidReportDescriptorTest, TopLevelCollections_Mouse) { 394 TEST_F(HidReportDescriptorTest, ValidateDetails_Mouse) {
537 HidUsageAndPage expected[] = { 395 HidCollectionInfo mouse;
538 HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop)}; 396 mouse.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop);
539 397 HidCollectionInfo expected[] = {mouse};
540 GetTopLevelCollections(std::vector<HidUsageAndPage>( 398 ValidateDetails(std::vector<HidCollectionInfo>(
541 expected, expected + ARRAYSIZE_UNSAFE(expected)), 399 expected, expected + ARRAYSIZE_UNSAFE(expected)),
542 kMouse, 400 3,
543 sizeof(kMouse)); 401 0,
402 0,
403 kMouse,
404 sizeof(kMouse));
544 } 405 }
545 406
546 TEST_F(HidReportDescriptorTest, ParseDescriptor_LogitechUnifyingReceiver) { 407 TEST_F(HidReportDescriptorTest, ValidateDetails_LogitechUnifyingReceiver) {
547 const char expected[] = { 408 HidCollectionInfo hidpp_short;
548 "Usage Page (Vendor)\n" 409 hidpp_short.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageVendor);
549 "Usage (0x1)\n" 410 hidpp_short.report_ids.insert(0x10);
550 "Collection (Physical)\n" 411 HidCollectionInfo hidpp_long;
551 " Report ID (0x10)\n" 412 hidpp_long.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageVendor);
552 " Report Size (8)\n" 413 hidpp_long.report_ids.insert(0x11);
553 " Report Count (6)\n" 414 HidCollectionInfo hidpp_dj;
554 " Logical Minimum (0)\n" 415 hidpp_dj.usage = HidUsageAndPage(0x04, HidUsageAndPage::kPageVendor);
555 " Logical Maximum (255)\n" 416 hidpp_dj.report_ids.insert(0x20);
556 " Usage (0x1)\n" 417 hidpp_dj.report_ids.insert(0x21);
557 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
558 " Usage (0x1)\n"
559 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
560 "End Collection\n"
561 "Usage Page (Vendor)\n"
562 "Usage (0x2)\n"
563 "Collection (Physical)\n"
564 " Report ID (0x11)\n"
565 " Report Size (8)\n"
566 " Report Count (19)\n"
567 " Logical Minimum (0)\n"
568 " Logical Maximum (255)\n"
569 " Usage (0x2)\n"
570 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
571 " Usage (0x2)\n"
572 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
573 "End Collection\n"
574 "Usage Page (Vendor)\n"
575 "Usage (0x4)\n"
576 "Collection (Physical)\n"
577 " Report ID (0x20)\n"
578 " Report Size (8)\n"
579 " Report Count (14)\n"
580 " Logical Minimum (0)\n"
581 " Logical Maximum (255)\n"
582 " Usage (0x41)\n"
583 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
584 " Usage (0x41)\n"
585 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
586 " Report ID (0x21)\n"
587 " Report Count (31)\n"
588 " Logical Minimum (0)\n"
589 " Logical Maximum (255)\n"
590 " Usage (0x42)\n"
591 " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
592 " Usage (0x42)\n"
593 " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
594 "End Collection\n"};
595 418
596 ParseDescriptor(std::string(expected), 419 HidCollectionInfo expected[] = {hidpp_short, hidpp_long, hidpp_dj};
420 ValidateDetails(std::vector<HidCollectionInfo>(
421 expected, expected + ARRAYSIZE_UNSAFE(expected)),
422 32,
423 32,
424 0,
597 kLogitechUnifyingReceiver, 425 kLogitechUnifyingReceiver,
598 sizeof(kLogitechUnifyingReceiver)); 426 sizeof(kLogitechUnifyingReceiver));
599 } 427 }
600 428
601 TEST_F(HidReportDescriptorTest, TopLevelCollections_LogitechUnifyingReceiver) {
602 HidUsageAndPage expected[] = {
603 HidUsageAndPage(0x01, HidUsageAndPage::kPageVendor),
604 HidUsageAndPage(0x02, HidUsageAndPage::kPageVendor),
605 HidUsageAndPage(0x04, HidUsageAndPage::kPageVendor), };
606
607 GetTopLevelCollections(std::vector<HidUsageAndPage>(
608 expected, expected + ARRAYSIZE_UNSAFE(expected)),
609 kLogitechUnifyingReceiver,
610 sizeof(kLogitechUnifyingReceiver));
611 }
612
613 } // namespace device 429 } // namespace device
OLDNEW
« no previous file with comments | « trunk/src/device/hid/hid_report_descriptor_item.cc ('k') | trunk/src/device/hid/hid_service_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698