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

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

Issue 369923002: Revert 281133 "chrome.hid: enrich model with report IDs" (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:
Deleted: 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 // Digitizer descriptor from HID descriptor tool 17 std::ostream& operator<<(std::ostream& os,
18 // http://www.usb.org/developers/hidpage/dt2_4.zip 18 const HidUsageAndPage::Page& usage_page) {
19 const uint8_t kDigitizer[] = { 19 switch (usage_page) {
20 0x05, 0x0d, // Usage Page (Digitizer) 20 case HidUsageAndPage::kPageUndefined:
21 0x09, 0x01, // Usage (0x1) 21 os << "Undefined";
22 0xa1, 0x01, // Collection (Application) 22 break;
23 0x85, 0x01, // Report ID (0x1) 23 case HidUsageAndPage::kPageGenericDesktop:
24 0x09, 0x21, // Usage (0x21) 24 os << "Generic Desktop";
25 0xa1, 0x00, // Collection (Physical) 25 break;
26 0x05, 0x01, // Usage Page (Generic Desktop) 26 case HidUsageAndPage::kPageSimulation:
27 0x09, 0x30, // Usage (0x30) 27 os << "Simulation";
28 0x09, 0x31, // Usage (0x31) 28 break;
29 0x75, 0x10, // Report Size (16) 29 case HidUsageAndPage::kPageVirtualReality:
30 0x95, 0x02, // Report Count (2) 30 os << "Virtual Reality";
31 0x15, 0x00, // Logical Minimum (0) 31 break;
32 0x26, 0xe0, 0x2e, // Logical Maximum (12000) 32 case HidUsageAndPage::kPageSport:
33 0x35, 0x00, // Physical Minimum (0) 33 os << "Sport";
34 0x45, 0x0c, // Physical Maximum (12) 34 break;
35 0x65, 0x13, // Unit (19) 35 case HidUsageAndPage::kPageGame:
36 0x55, 0x00, // Unit Exponent (0) 36 os << "Game";
37 0xa4, // Push 37 break;
38 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 38 case HidUsageAndPage::kPageKeyboard:
39 0x05, 0x0d, // Usage Page (Digitizer) 39 os << "Keyboard";
40 0x09, 0x32, // Usage (0x32) 40 break;
41 0x09, 0x44, // Usage (0x44) 41 case HidUsageAndPage::kPageLed:
42 0x09, 0x42, // Usage (0x42) 42 os << "Led";
43 0x15, 0x00, // Logical Minimum (0) 43 break;
44 0x25, 0x01, // Logical Maximum (1) 44 case HidUsageAndPage::kPageButton:
45 0x35, 0x00, // Physical Minimum (0) 45 os << "Button";
46 0x45, 0x01, // Physical Maximum (1) 46 break;
47 0x75, 0x01, // Report Size (1) 47 case HidUsageAndPage::kPageOrdinal:
48 0x95, 0x03, // Report Count (3) 48 os << "Ordinal";
49 0x65, 0x00, // Unit (0) 49 break;
50 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 50 case HidUsageAndPage::kPageTelephony:
51 0x95, 0x01, // Report Count (1) 51 os << "Telephony";
52 0x75, 0x05, // Report Size (5) 52 break;
53 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 53 case HidUsageAndPage::kPageConsumer:
54 0xc0, // End Collection 54 os << "Consumer";
55 0x85, 0x02, // Report ID (0x2) 55 break;
56 0x09, 0x20, // Usage (0x20) 56 case HidUsageAndPage::kPageDigitizer:
57 0xa1, 0x00, // Collection (Physical) 57 os << "Digitizer";
58 0xb4, // Pop 58 break;
59 0xa4, // Push 59 case HidUsageAndPage::kPagePidPage:
60 0x09, 0x30, // Usage (0x30) 60 os << "Pid Page";
61 0x09, 0x31, // Usage (0x31) 61 break;
62 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 62 case HidUsageAndPage::kPageUnicode:
63 0x05, 0x0d, // Usage Page (Digitizer) 63 os << "Unicode";
64 0x09, 0x32, // Usage (0x32) 64 break;
65 0x15, 0x00, // Logical Minimum (0) 65 case HidUsageAndPage::kPageAlphanumericDisplay:
66 0x25, 0x01, // Logical Maximum (1) 66 os << "Alphanumeric Display";
67 0x35, 0x00, // Physical Minimum (0) 67 break;
68 0x45, 0x01, // Physical Maximum (1) 68 case HidUsageAndPage::kPageMedicalInstruments:
69 0x65, 0x00, // Unit (0) 69 os << "Medical Instruments";
70 0x75, 0x01, // Report Size (1) 70 break;
71 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 71 case HidUsageAndPage::kPageMonitor0:
72 0x05, 0x09, // Usage Page (Button) 72 os << "Monitor 0";
73 0x19, 0x00, // Usage Minimum (0) 73 break;
74 0x29, 0x10, // Usage Maximum (16) 74 case HidUsageAndPage::kPageMonitor1:
75 0x25, 0x10, // Logical Maximum (16) 75 os << "Monitor 1";
76 0x75, 0x05, // Report Size (5) 76 break;
77 0x81, 0x40, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|Null|BitF) 77 case HidUsageAndPage::kPageMonitor2:
78 0x75, 0x02, // Report Size (2) 78 os << "Monitor 2";
79 0x81, 0x01, // Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) 79 break;
80 0xc0, // End Collection 80 case HidUsageAndPage::kPageMonitor3:
81 0x85, 0x03, // Report ID (0x3) 81 os << "Monitor 3";
82 0x05, 0x0d, // Usage Page (Digitizer) 82 break;
83 0x09, 0x20, // Usage (0x20) 83 case HidUsageAndPage::kPagePower0:
84 0xa1, 0x00, // Collection (Physical) 84 os << "Power 0";
85 0xb4, // Pop 85 break;
86 0x09, 0x30, // Usage (0x30) 86 case HidUsageAndPage::kPagePower1:
87 0x09, 0x31, // Usage (0x31) 87 os << "Power 1";
88 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 88 break;
89 0x05, 0x0d, // Usage Page (Digitizer) 89 case HidUsageAndPage::kPagePower2:
90 0x09, 0x32, // Usage (0x32) 90 os << "Power 2";
91 0x09, 0x44, // Usage (0x44) 91 break;
92 0x75, 0x01, // Report Size (1) 92 case HidUsageAndPage::kPagePower3:
93 0x15, 0x00, // Logical Minimum (0) 93 os << "Power 3";
94 0x25, 0x01, // Logical Maximum (1) 94 break;
95 0x35, 0x00, // Physical Minimum (0) 95 case HidUsageAndPage::kPageBarCodeScanner:
96 0x45, 0x01, // Physical Maximum (1) 96 os << "Bar Code Scanner";
97 0x65, 0x00, // Unit (0) 97 break;
98 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 98 case HidUsageAndPage::kPageScale:
99 0x95, 0x06, // Report Count (6) 99 os << "Scale";
100 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 100 break;
101 0x09, 0x30, // Usage (0x30) 101 case HidUsageAndPage::kPageMagneticStripeReader:
102 0x15, 0x00, // Logical Minimum (0) 102 os << "Magnetic Stripe Reader";
103 0x25, 0x7f, // Logical Maximum (127) 103 break;
104 0x35, 0x00, // Physical Minimum (0) 104 case HidUsageAndPage::kPageReservedPointOfSale:
105 0x45, 0x2d, // Physical Maximum (45) 105 os << "Reserved Point Of Sale";
106 0x67, 0x11, 0xe1, // Unit (57617) 106 break;
107 0x00, 0x00, // Default 107 case HidUsageAndPage::kPageCameraControl:
108 0x55, 0x04, // Unit Exponent (4) 108 os << "Camera Control";
109 0x75, 0x08, // Report Size (8) 109 break;
110 0x95, 0x01, // Report Count (1) 110 case HidUsageAndPage::kPageArcade:
111 0x81, 0x12, // Input (Dat|Arr|Rel|NoWrp|NoLin|Prf|NoNull|BitF) 111 os << "Arcade";
112 0xc0, // End Collection 112 break;
113 0xc0 // End Collection 113 case HidUsageAndPage::kPageVendor:
114 }; 114 os << "Vendor";
115 115 break;
116 // Keyboard descriptor from HID descriptor tool 116 case HidUsageAndPage::kPageMediaCenter:
117 // http://www.usb.org/developers/hidpage/dt2_4.zip 117 os << "Media Center";
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)
118 const uint8_t kKeyboard[] = { 376 const uint8_t kKeyboard[] = {
119 0x05, 0x01, // Usage Page (Generic Desktop) 377 0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0, 0x29,
120 0x09, 0x06, // Usage (0x6) 378 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02,
121 0xa1, 0x01, // Collection (Application) 379 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05, 0x75, 0x01, 0x05,
122 0x05, 0x07, // Usage Page (Keyboard) 380 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03,
123 0x19, 0xe0, // Usage Minimum (224) 381 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05,
124 0x29, 0xe7, // Usage Maximum (231) 382 0x07, 0x19, 0x00, 0x29, 0x65, 0x81, 0x00, 0xC0};
125 0x15, 0x00, // Logical Minimum (0) 383
126 0x25, 0x01, // Logical Maximum (1) 384 // See 'E.10 Report Descriptor (Mouse)'
127 0x75, 0x01, // Report Size (1) 385 // in HID specifications (v1.11)
128 0x95, 0x08, // Report Count (8) 386 const uint8_t kMouse[] = {0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1,
129 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 387 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00,
130 0x95, 0x01, // Report Count (1) 388 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95,
131 0x75, 0x08, // Report Size (8) 389 0x01, 0x75, 0x05, 0x81, 0x01, 0x05, 0x01, 0x09, 0x30,
132 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) 390 0x09, 0x31, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95,
133 0x95, 0x05, // Report Count (5) 391 0x02, 0x81, 0x06, 0xC0, 0xC0};
134 0x75, 0x01, // Report Size (1) 392
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[] = { 393 const uint8_t kLogitechUnifyingReceiver[] = {
235 0x06, 0x00, 0xFF, // Usage Page (Vendor) 394 0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x75, 0x08,
236 0x09, 0x01, // Usage (0x1) 395 0x95, 0x06, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x09, 0x01, 0x81, 0x00,
237 0xA1, 0x01, // Collection (Application) 396 0x09, 0x01, 0x91, 0x00, 0xC0, 0x06, 0x00, 0xFF, 0x09, 0x02, 0xA1,
238 0x85, 0x10, // Report ID (0x10) 397 0x01, 0x85, 0x11, 0x75, 0x08, 0x95, 0x13, 0x15, 0x00, 0x26, 0xFF,
239 0x75, 0x08, // Report Size (8) 398 0x00, 0x09, 0x02, 0x81, 0x00, 0x09, 0x02, 0x91, 0x00, 0xC0, 0x06,
240 0x95, 0x06, // Report Count (6) 399 0x00, 0xFF, 0x09, 0x04, 0xA1, 0x01, 0x85, 0x20, 0x75, 0x08, 0x95,
241 0x15, 0x00, // Logical Minimum (0) 400 0x0E, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x09, 0x41, 0x81, 0x00, 0x09,
242 0x26, 0xFF, 0x00, // Logical Maximum (255) 401 0x41, 0x91, 0x00, 0x85, 0x21, 0x95, 0x1F, 0x15, 0x00, 0x26, 0xFF,
243 0x09, 0x01, // Usage (0x1) 402 0x00, 0x09, 0x42, 0x81, 0x00, 0x09, 0x42, 0x91, 0x00, 0xC0};
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 403
284 } // namespace 404 } // namespace
285 405
286 class HidReportDescriptorTest : public testing::Test { 406 class HidReportDescriptorTest : public testing::Test {
287 407
288 protected: 408 protected:
289 virtual void SetUp() OVERRIDE { descriptor_ = NULL; } 409 virtual void SetUp() OVERRIDE { descriptor_ = NULL; }
290 410
291 virtual void TearDown() OVERRIDE { 411 virtual void TearDown() OVERRIDE {
292 if (descriptor_) { 412 if (descriptor_) {
293 delete descriptor_; 413 delete descriptor_;
294 } 414 }
295 } 415 }
296 416
297 public: 417 public:
298 void ValidateDetails( 418 void ParseDescriptor(const std::string& expected,
299 const std::vector<HidCollectionInfo>& expected_collections, 419 const uint8_t* bytes,
300 const int expected_max_input_report_size, 420 size_t 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) {
305 descriptor_ = new HidReportDescriptor(bytes, size); 421 descriptor_ = new HidReportDescriptor(bytes, size);
306 422
307 std::vector<HidCollectionInfo> actual_collections; 423 std::stringstream actual;
308 int actual_max_input_report_size; 424 actual << *descriptor_;
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);
315 425
316 ASSERT_EQ(expected_collections.size(), actual_collections.size()); 426 std::cout << "HID report descriptor:" << std::endl;
427 std::cout << actual.str();
317 428
318 std::vector<HidCollectionInfo>::const_iterator actual_collections_iter = 429 // TODO(jracle@logitech.com): refactor string comparison in favor of
319 actual_collections.begin(); 430 // testing individual fields.
320 std::vector<HidCollectionInfo>::const_iterator expected_collections_iter = 431 ASSERT_EQ(expected, actual.str());
321 expected_collections.begin(); 432 }
322 433
323 while (expected_collections_iter != expected_collections.end() && 434 void GetTopLevelCollections(const std::vector<HidUsageAndPage>& expected,
324 actual_collections_iter != actual_collections.end()) { 435 const uint8_t* bytes,
325 HidCollectionInfo expected_collection = *expected_collections_iter; 436 size_t size) {
326 HidCollectionInfo actual_collection = *actual_collections_iter; 437 descriptor_ = new HidReportDescriptor(bytes, size);
327 438
328 ASSERT_EQ(expected_collection.usage.usage_page, 439 std::vector<HidUsageAndPage> actual;
329 actual_collection.usage.usage_page); 440 descriptor_->GetTopLevelCollections(&actual);
330 ASSERT_EQ(expected_collection.usage.usage, actual_collection.usage.usage);
331 ASSERT_THAT(actual_collection.report_ids,
332 ContainerEq(expected_collection.report_ids));
333 441
334 expected_collections_iter++; 442 std::cout << "HID top-level collections:" << std::endl;
335 actual_collections_iter++; 443 for (std::vector<HidUsageAndPage>::const_iterator iter = actual.begin();
444 iter != actual.end();
445 ++iter) {
446 std::cout << *iter << std::endl;
336 } 447 }
337 448
338 ASSERT_EQ(expected_max_input_report_size, actual_max_input_report_size); 449 ASSERT_THAT(actual, ContainerEq(expected));
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);
341 } 450 }
342 451
343 private: 452 private:
344 HidReportDescriptor* descriptor_; 453 HidReportDescriptor* descriptor_;
345 }; 454 };
346 455
347 TEST_F(HidReportDescriptorTest, ValidateDetails_Digitizer) { 456 TEST_F(HidReportDescriptorTest, ParseDescriptor_Keyboard) {
348 HidCollectionInfo digitizer; 457 const char expected[] = {
349 digitizer.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageDigitizer); 458 "Usage Page (Generic Desktop)\n"
350 digitizer.report_ids.insert(1); 459 "Usage (0x6)\n"
351 digitizer.report_ids.insert(2); 460 "Collection (Physical)\n"
352 digitizer.report_ids.insert(3); 461 " Usage Page (Keyboard)\n"
353 HidCollectionInfo expected[] = {digitizer}; 462 " Usage Minimum (224)\n"
354 ValidateDetails(std::vector<HidCollectionInfo>( 463 " Usage Maximum (231)\n"
355 expected, expected + ARRAYSIZE_UNSAFE(expected)), 464 " Logical Minimum (0)\n"
356 7, 465 " Logical Maximum (1)\n"
357 0, 466 " Report Size (1)\n"
358 0, 467 " Report Count (8)\n"
359 kDigitizer, 468 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
360 sizeof(kDigitizer)); 469 " Report Count (1)\n"
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));
361 } 492 }
362 493
363 TEST_F(HidReportDescriptorTest, ValidateDetails_Keyboard) { 494 TEST_F(HidReportDescriptorTest, TopLevelCollections_Keyboard) {
364 HidCollectionInfo keyboard; 495 HidUsageAndPage expected[] = {
365 keyboard.usage = HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop); 496 HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop)};
366 HidCollectionInfo expected[] = {keyboard}; 497
367 ValidateDetails(std::vector<HidCollectionInfo>( 498 GetTopLevelCollections(std::vector<HidUsageAndPage>(
368 expected, expected + ARRAYSIZE_UNSAFE(expected)), 499 expected, expected + ARRAYSIZE_UNSAFE(expected)),
369 8, 500 kKeyboard,
370 1, 501 sizeof(kKeyboard));
371 0,
372 kKeyboard,
373 sizeof(kKeyboard));
374 } 502 }
375 503
376 TEST_F(HidReportDescriptorTest, ValidateDetails_Monitor) { 504 TEST_F(HidReportDescriptorTest, ParseDescriptor_Mouse) {
377 HidCollectionInfo monitor; 505 const char expected[] = {
378 monitor.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageMonitor0); 506 "Usage Page (Generic Desktop)\n"
379 monitor.report_ids.insert(1); 507 "Usage (0x2)\n"
380 monitor.report_ids.insert(2); 508 "Collection (Physical)\n"
381 monitor.report_ids.insert(3); 509 " Usage (0x1)\n"
382 monitor.report_ids.insert(4); 510 " Collection (Physical)\n"
383 monitor.report_ids.insert(5); 511 " Usage Page (Button)\n"
384 HidCollectionInfo expected[] = {monitor}; 512 " Usage Minimum (1)\n"
385 ValidateDetails(std::vector<HidCollectionInfo>( 513 " Usage Maximum (3)\n"
386 expected, expected + ARRAYSIZE_UNSAFE(expected)), 514 " Logical Minimum (0)\n"
387 0, 515 " Logical Maximum (1)\n"
388 0, 516 " Report Count (3)\n"
389 244, 517 " Report Size (1)\n"
390 kMonitor, 518 " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n"
391 sizeof(kMonitor)); 519 " Report Count (1)\n"
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));
392 } 534 }
393 535
394 TEST_F(HidReportDescriptorTest, ValidateDetails_Mouse) { 536 TEST_F(HidReportDescriptorTest, TopLevelCollections_Mouse) {
395 HidCollectionInfo mouse; 537 HidUsageAndPage expected[] = {
396 mouse.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop); 538 HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop)};
397 HidCollectionInfo expected[] = {mouse}; 539
398 ValidateDetails(std::vector<HidCollectionInfo>( 540 GetTopLevelCollections(std::vector<HidUsageAndPage>(
399 expected, expected + ARRAYSIZE_UNSAFE(expected)), 541 expected, expected + ARRAYSIZE_UNSAFE(expected)),
400 3, 542 kMouse,
401 0, 543 sizeof(kMouse));
402 0,
403 kMouse,
404 sizeof(kMouse));
405 } 544 }
406 545
407 TEST_F(HidReportDescriptorTest, ValidateDetails_LogitechUnifyingReceiver) { 546 TEST_F(HidReportDescriptorTest, ParseDescriptor_LogitechUnifyingReceiver) {
408 HidCollectionInfo hidpp_short; 547 const char expected[] = {
409 hidpp_short.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageVendor); 548 "Usage Page (Vendor)\n"
410 hidpp_short.report_ids.insert(0x10); 549 "Usage (0x1)\n"
411 HidCollectionInfo hidpp_long; 550 "Collection (Physical)\n"
412 hidpp_long.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageVendor); 551 " Report ID (0x10)\n"
413 hidpp_long.report_ids.insert(0x11); 552 " Report Size (8)\n"
414 HidCollectionInfo hidpp_dj; 553 " Report Count (6)\n"
415 hidpp_dj.usage = HidUsageAndPage(0x04, HidUsageAndPage::kPageVendor); 554 " Logical Minimum (0)\n"
416 hidpp_dj.report_ids.insert(0x20); 555 " Logical Maximum (255)\n"
417 hidpp_dj.report_ids.insert(0x21); 556 " Usage (0x1)\n"
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"};
418 595
419 HidCollectionInfo expected[] = {hidpp_short, hidpp_long, hidpp_dj}; 596 ParseDescriptor(std::string(expected),
420 ValidateDetails(std::vector<HidCollectionInfo>(
421 expected, expected + ARRAYSIZE_UNSAFE(expected)),
422 32,
423 32,
424 0,
425 kLogitechUnifyingReceiver, 597 kLogitechUnifyingReceiver,
426 sizeof(kLogitechUnifyingReceiver)); 598 sizeof(kLogitechUnifyingReceiver));
427 } 599 }
428 600
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
429 } // namespace device 613 } // 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