diff options
author | csharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-03 17:14:13 +0000 |
---|---|---|
committer | csharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-03 17:14:13 +0000 |
commit | 0eac598eeed59ebebdeb0d44e93677fbb9cb9d5a (patch) | |
tree | 6c5033490339860687bd80a6f6a663784eddd654 /device/hid/hid_report_descriptor_unittest.cc | |
parent | c9ab4198a25ff667f69acc6c9c8dad10c81bbe64 (diff) | |
download | chromium_src-0eac598eeed59ebebdeb0d44e93677fbb9cb9d5a.zip chromium_src-0eac598eeed59ebebdeb0d44e93677fbb9cb9d5a.tar.gz chromium_src-0eac598eeed59ebebdeb0d44e93677fbb9cb9d5a.tar.bz2 |
Revert 281133 "chrome.hid: enrich model with report IDs"
Speculative revert to try and fix Win browser tests.
> chrome.hid: enrich model with report IDs
>
> - add report IDs and max report size
> - don't expose sensitive usages
>
> BUG=364423
> R=rockot@chromium.org
> TESTS=run device_unittests (HidReportDescriptorTest)
>
> Review URL: https://codereview.chromium.org/317783010
TBR=jracle@logitech.com
Review URL: https://codereview.chromium.org/369923002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281282 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device/hid/hid_report_descriptor_unittest.cc')
-rw-r--r-- | device/hid/hid_report_descriptor_unittest.cc | 924 |
1 files changed, 554 insertions, 370 deletions
diff --git a/device/hid/hid_report_descriptor_unittest.cc b/device/hid/hid_report_descriptor_unittest.cc index 619e682..0d25889 100644 --- a/device/hid/hid_report_descriptor_unittest.cc +++ b/device/hid/hid_report_descriptor_unittest.cc @@ -14,272 +14,392 @@ namespace device { namespace { -// Digitizer descriptor from HID descriptor tool -// http://www.usb.org/developers/hidpage/dt2_4.zip -const uint8_t kDigitizer[] = { - 0x05, 0x0d, // Usage Page (Digitizer) - 0x09, 0x01, // Usage (0x1) - 0xa1, 0x01, // Collection (Application) - 0x85, 0x01, // Report ID (0x1) - 0x09, 0x21, // Usage (0x21) - 0xa1, 0x00, // Collection (Physical) - 0x05, 0x01, // Usage Page (Generic Desktop) - 0x09, 0x30, // Usage (0x30) - 0x09, 0x31, // Usage (0x31) - 0x75, 0x10, // Report Size (16) - 0x95, 0x02, // Report Count (2) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xe0, 0x2e, // Logical Maximum (12000) - 0x35, 0x00, // Physical Minimum (0) - 0x45, 0x0c, // Physical Maximum (12) - 0x65, 0x13, // Unit (19) - 0x55, 0x00, // Unit Exponent (0) - 0xa4, // Push - 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x05, 0x0d, // Usage Page (Digitizer) - 0x09, 0x32, // Usage (0x32) - 0x09, 0x44, // Usage (0x44) - 0x09, 0x42, // Usage (0x42) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x35, 0x00, // Physical Minimum (0) - 0x45, 0x01, // Physical Maximum (1) - 0x75, 0x01, // Report Size (1) - 0x95, 0x03, // Report Count (3) - 0x65, 0x00, // Unit (0) - 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x95, 0x01, // Report Count (1) - 0x75, 0x05, // Report Size (5) - 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0xc0, // End Collection - 0x85, 0x02, // Report ID (0x2) - 0x09, 0x20, // Usage (0x20) - 0xa1, 0x00, // Collection (Physical) - 0xb4, // Pop - 0xa4, // Push - 0x09, 0x30, // Usage (0x30) - 0x09, 0x31, // Usage (0x31) - 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x05, 0x0d, // Usage Page (Digitizer) - 0x09, 0x32, // Usage (0x32) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x35, 0x00, // Physical Minimum (0) - 0x45, 0x01, // Physical Maximum (1) - 0x65, 0x00, // Unit (0) - 0x75, 0x01, // Report Size (1) - 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x05, 0x09, // Usage Page (Button) - 0x19, 0x00, // Usage Minimum (0) - 0x29, 0x10, // Usage Maximum (16) - 0x25, 0x10, // Logical Maximum (16) - 0x75, 0x05, // Report Size (5) - 0x81, 0x40, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|Null|BitF) - 0x75, 0x02, // Report Size (2) - 0x81, 0x01, // Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0xc0, // End Collection - 0x85, 0x03, // Report ID (0x3) - 0x05, 0x0d, // Usage Page (Digitizer) - 0x09, 0x20, // Usage (0x20) - 0xa1, 0x00, // Collection (Physical) - 0xb4, // Pop - 0x09, 0x30, // Usage (0x30) - 0x09, 0x31, // Usage (0x31) - 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x05, 0x0d, // Usage Page (Digitizer) - 0x09, 0x32, // Usage (0x32) - 0x09, 0x44, // Usage (0x44) - 0x75, 0x01, // Report Size (1) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x35, 0x00, // Physical Minimum (0) - 0x45, 0x01, // Physical Maximum (1) - 0x65, 0x00, // Unit (0) - 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x95, 0x06, // Report Count (6) - 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x09, 0x30, // Usage (0x30) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x7f, // Logical Maximum (127) - 0x35, 0x00, // Physical Minimum (0) - 0x45, 0x2d, // Physical Maximum (45) - 0x67, 0x11, 0xe1, // Unit (57617) - 0x00, 0x00, // Default - 0x55, 0x04, // Unit Exponent (4) - 0x75, 0x08, // Report Size (8) - 0x95, 0x01, // Report Count (1) - 0x81, 0x12, // Input (Dat|Arr|Rel|NoWrp|NoLin|Prf|NoNull|BitF) - 0xc0, // End Collection - 0xc0 // End Collection -}; +std::ostream& operator<<(std::ostream& os, + const HidUsageAndPage::Page& usage_page) { + switch (usage_page) { + case HidUsageAndPage::kPageUndefined: + os << "Undefined"; + break; + case HidUsageAndPage::kPageGenericDesktop: + os << "Generic Desktop"; + break; + case HidUsageAndPage::kPageSimulation: + os << "Simulation"; + break; + case HidUsageAndPage::kPageVirtualReality: + os << "Virtual Reality"; + break; + case HidUsageAndPage::kPageSport: + os << "Sport"; + break; + case HidUsageAndPage::kPageGame: + os << "Game"; + break; + case HidUsageAndPage::kPageKeyboard: + os << "Keyboard"; + break; + case HidUsageAndPage::kPageLed: + os << "Led"; + break; + case HidUsageAndPage::kPageButton: + os << "Button"; + break; + case HidUsageAndPage::kPageOrdinal: + os << "Ordinal"; + break; + case HidUsageAndPage::kPageTelephony: + os << "Telephony"; + break; + case HidUsageAndPage::kPageConsumer: + os << "Consumer"; + break; + case HidUsageAndPage::kPageDigitizer: + os << "Digitizer"; + break; + case HidUsageAndPage::kPagePidPage: + os << "Pid Page"; + break; + case HidUsageAndPage::kPageUnicode: + os << "Unicode"; + break; + case HidUsageAndPage::kPageAlphanumericDisplay: + os << "Alphanumeric Display"; + break; + case HidUsageAndPage::kPageMedicalInstruments: + os << "Medical Instruments"; + break; + case HidUsageAndPage::kPageMonitor0: + os << "Monitor 0"; + break; + case HidUsageAndPage::kPageMonitor1: + os << "Monitor 1"; + break; + case HidUsageAndPage::kPageMonitor2: + os << "Monitor 2"; + break; + case HidUsageAndPage::kPageMonitor3: + os << "Monitor 3"; + break; + case HidUsageAndPage::kPagePower0: + os << "Power 0"; + break; + case HidUsageAndPage::kPagePower1: + os << "Power 1"; + break; + case HidUsageAndPage::kPagePower2: + os << "Power 2"; + break; + case HidUsageAndPage::kPagePower3: + os << "Power 3"; + break; + case HidUsageAndPage::kPageBarCodeScanner: + os << "Bar Code Scanner"; + break; + case HidUsageAndPage::kPageScale: + os << "Scale"; + break; + case HidUsageAndPage::kPageMagneticStripeReader: + os << "Magnetic Stripe Reader"; + break; + case HidUsageAndPage::kPageReservedPointOfSale: + os << "Reserved Point Of Sale"; + break; + case HidUsageAndPage::kPageCameraControl: + os << "Camera Control"; + break; + case HidUsageAndPage::kPageArcade: + os << "Arcade"; + break; + case HidUsageAndPage::kPageVendor: + os << "Vendor"; + break; + case HidUsageAndPage::kPageMediaCenter: + os << "Media Center"; + break; + default: + NOTREACHED(); + break; + } + return os; +} -// Keyboard descriptor from HID descriptor tool -// http://www.usb.org/developers/hidpage/dt2_4.zip -const uint8_t kKeyboard[] = { - 0x05, 0x01, // Usage Page (Generic Desktop) - 0x09, 0x06, // Usage (0x6) - 0xa1, 0x01, // Collection (Application) - 0x05, 0x07, // Usage Page (Keyboard) - 0x19, 0xe0, // Usage Minimum (224) - 0x29, 0xe7, // Usage Maximum (231) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x75, 0x01, // Report Size (1) - 0x95, 0x08, // Report Count (8) - 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x95, 0x01, // Report Count (1) - 0x75, 0x08, // Report Size (8) - 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x95, 0x05, // Report Count (5) - 0x75, 0x01, // Report Size (1) - 0x05, 0x08, // Usage Page (Led) - 0x19, 0x01, // Usage Minimum (1) - 0x29, 0x05, // Usage Maximum (5) - 0x91, 0x02, // Output (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x95, 0x01, // Report Count (1) - 0x75, 0x03, // Report Size (3) - 0x91, 0x03, // Output (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x95, 0x06, // Report Count (6) - 0x75, 0x08, // Report Size (8) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x65, // Logical Maximum (101) - 0x05, 0x07, // Usage Page (Keyboard) - 0x19, 0x00, // Usage Minimum (0) - 0x29, 0x65, // Usage Maximum (101) - 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0xc0 // End Collection -}; +std::ostream& operator<<(std::ostream& os, + const HidUsageAndPage& usage_and_page) { + os << "Usage Page: " << usage_and_page.usage_page << ", Usage: " + << "0x" << std::hex << std::uppercase << usage_and_page.usage; + return os; +} -// Monitor descriptor from HID descriptor tool -// http://www.usb.org/developers/hidpage/dt2_4.zip -const uint8_t kMonitor[] = { - 0x05, 0x80, // Usage Page (Monitor 0) - 0x09, 0x01, // Usage (0x1) - 0xa1, 0x01, // Collection (Application) - 0x85, 0x01, // Report ID (0x1) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xff, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8) - 0x95, 0x80, // Report Count (128) - 0x09, 0x02, // Usage (0x2) - 0xb2, 0x02, 0x01, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|Buff) - 0x85, 0x02, // Report ID (0x2) - 0x95, 0xf3, // Report Count (243) - 0x09, 0x03, // Usage (0x3) - 0xb2, 0x02, 0x01, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|Buff) - 0x85, 0x03, // Report ID (0x3) - 0x05, 0x82, // Usage Page (Monitor 2) - 0x95, 0x01, // Report Count (1) - 0x75, 0x10, // Report Size (16) - 0x26, 0xc8, 0x00, // Logical Maximum (200) - 0x09, 0x10, // Usage (0x10) - 0xb1, 0x02, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x85, 0x04, // Report ID (0x4) - 0x25, 0x64, // Logical Maximum (100) - 0x09, 0x12, // Usage (0x12) - 0xb1, 0x02, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x95, 0x06, // Report Count (6) - 0x26, 0xff, 0x00, // Logical Maximum (255) - 0x09, 0x16, // Usage (0x16) - 0x09, 0x18, // Usage (0x18) - 0x09, 0x1a, // Usage (0x1A) - 0x09, 0x6c, // Usage (0x6C) - 0x09, 0x6e, // Usage (0x6E) - 0x09, 0x70, // Usage (0x70) - 0xb1, 0x02, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x85, 0x05, // Report ID (0x5) - 0x25, 0x7f, // Logical Maximum (127) - 0x09, 0x20, // Usage (0x20) - 0x09, 0x22, // Usage (0x22) - 0x09, 0x30, // Usage (0x30) - 0x09, 0x32, // Usage (0x32) - 0x09, 0x42, // Usage (0x42) - 0x09, 0x44, // Usage (0x44) - 0xb1, 0x02, // Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0xc0 // End Collection -}; +std::ostream& operator<<(std::ostream& os, + const HidReportDescriptorItem::Tag& tag) { + switch (tag) { + case HidReportDescriptorItem::kTagDefault: + os << "Default"; + break; + case HidReportDescriptorItem::kTagInput: + os << "Input"; + break; + case HidReportDescriptorItem::kTagOutput: + os << "Output"; + break; + case HidReportDescriptorItem::kTagFeature: + os << "Feature"; + break; + case HidReportDescriptorItem::kTagCollection: + os << "Collection"; + break; + case HidReportDescriptorItem::kTagEndCollection: + os << "End Collection"; + break; + case HidReportDescriptorItem::kTagUsagePage: + os << "Usage Page"; + break; + case HidReportDescriptorItem::kTagLogicalMinimum: + os << "Logical Minimum"; + break; + case HidReportDescriptorItem::kTagLogicalMaximum: + os << "Logical Maximum"; + break; + case HidReportDescriptorItem::kTagPhysicalMinimum: + os << "Physical Minimum"; + break; + case HidReportDescriptorItem::kTagPhysicalMaximum: + os << "Physical Maximum"; + break; + case HidReportDescriptorItem::kTagUnitExponent: + os << "Unit Exponent"; + break; + case HidReportDescriptorItem::kTagUnit: + os << "Unit"; + break; + case HidReportDescriptorItem::kTagReportSize: + os << "Report Size"; + break; + case HidReportDescriptorItem::kTagReportId: + os << "Report ID"; + break; + case HidReportDescriptorItem::kTagReportCount: + os << "Report Count"; + break; + case HidReportDescriptorItem::kTagPush: + os << "Push"; + break; + case HidReportDescriptorItem::kTagPop: + os << "Pop"; + break; + case HidReportDescriptorItem::kTagUsage: + os << "Usage"; + break; + case HidReportDescriptorItem::kTagUsageMinimum: + os << "Usage Minimum"; + break; + case HidReportDescriptorItem::kTagUsageMaximum: + os << "Usage Maximum"; + break; + case HidReportDescriptorItem::kTagDesignatorIndex: + os << "Designator Index"; + break; + case HidReportDescriptorItem::kTagDesignatorMinimum: + os << "Designator Minimum"; + break; + case HidReportDescriptorItem::kTagDesignatorMaximum: + os << "Designator Maximum"; + break; + case HidReportDescriptorItem::kTagStringIndex: + os << "String Index"; + break; + case HidReportDescriptorItem::kTagStringMinimum: + os << "String Minimum"; + break; + case HidReportDescriptorItem::kTagStringMaximum: + os << "String Maximum"; + break; + case HidReportDescriptorItem::kTagDelimiter: + os << "Delimeter"; + break; + case HidReportDescriptorItem::kTagLong: + os << "Long"; + break; + default: + NOTREACHED(); + break; + } -// Mouse descriptor from HID descriptor tool -// http://www.usb.org/developers/hidpage/dt2_4.zip -const uint8_t kMouse[] = { - 0x05, 0x01, // Usage Page (Generic Desktop) - 0x09, 0x02, // Usage (0x2) - 0xa1, 0x01, // Collection (Application) - 0x09, 0x01, // Usage (0x1) - 0xa1, 0x00, // Collection (Physical) - 0x05, 0x09, // Usage Page (Button) - 0x19, 0x01, // Usage Minimum (1) - 0x29, 0x03, // Usage Maximum (3) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x95, 0x03, // Report Count (3) - 0x75, 0x01, // Report Size (1) - 0x81, 0x02, // Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x95, 0x01, // Report Count (1) - 0x75, 0x05, // Report Size (5) - 0x81, 0x03, // Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x05, 0x01, // Usage Page (Generic Desktop) - 0x09, 0x30, // Usage (0x30) - 0x09, 0x31, // Usage (0x31) - 0x15, 0x81, // Logical Minimum (129) - 0x25, 0x7f, // Logical Maximum (127) - 0x75, 0x08, // Report Size (8) - 0x95, 0x02, // Report Count (2) - 0x81, 0x06, // Input (Dat|Arr|Abs|NoWrp|Lin|Prf|NoNull|BitF) - 0xc0, // End Collection - 0xc0 // End Collection -}; + return os; +} + +std::ostream& operator<<(std::ostream& os, + const HidReportDescriptorItem::ReportInfo& data) { + if (data.data_or_constant) + os << "Con"; + else + os << "Dat"; + if (data.array_or_variable) + os << "|Arr"; + else + os << "|Var"; + if (data.absolute_or_relative) + os << "|Abs"; + else + os << "|Rel"; + if (data.wrap) + os << "|Wrp"; + else + os << "|NoWrp"; + if (data.linear) + os << "|NoLin"; + else + os << "|Lin"; + if (data.preferred) + os << "|NoPrf"; + else + os << "|Prf"; + if (data.null) + os << "|Null"; + else + os << "|NoNull"; + if (data.bit_field_or_buffer) + os << "|Buff"; + else + os << "|BitF"; + return os; +} + +std::ostream& operator<<(std::ostream& os, + const HidReportDescriptorItem::CollectionType& type) { + switch (type) { + case HidReportDescriptorItem::kCollectionTypePhysical: + os << "Physical"; + break; + case HidReportDescriptorItem::kCollectionTypeApplication: + os << "Application"; + break; + case HidReportDescriptorItem::kCollectionTypeLogical: + os << "Logical"; + break; + case HidReportDescriptorItem::kCollectionTypeReport: + os << "Report"; + break; + case HidReportDescriptorItem::kCollectionTypeNamedArray: + os << "Named Array"; + break; + case HidReportDescriptorItem::kCollectionTypeUsageSwitch: + os << "Usage Switch"; + break; + case HidReportDescriptorItem::kCollectionTypeUsageModifier: + os << "Usage Modifier"; + break; + case HidReportDescriptorItem::kCollectionTypeReserved: + os << "Reserved"; + break; + case HidReportDescriptorItem::kCollectionTypeVendor: + os << "Vendor"; + break; + default: + NOTREACHED(); + break; + } + return os; +} + +std::ostream& operator<<(std::ostream& os, + const HidReportDescriptorItem& item) { + HidReportDescriptorItem::Tag item_tag = item.tag(); + uint32_t data = item.GetShortData(); + + std::ostringstream sstr; + sstr << item_tag; + sstr << " ("; + + long pos = sstr.tellp(); + switch (item_tag) { + case HidReportDescriptorItem::kTagDefault: + case HidReportDescriptorItem::kTagEndCollection: + case HidReportDescriptorItem::kTagPush: + case HidReportDescriptorItem::kTagPop: + case HidReportDescriptorItem::kTagLong: + break; + + case HidReportDescriptorItem::kTagCollection: + sstr << HidReportDescriptorItem::GetCollectionTypeFromValue(data); + break; + + case HidReportDescriptorItem::kTagInput: + case HidReportDescriptorItem::kTagOutput: + case HidReportDescriptorItem::kTagFeature: + sstr << (HidReportDescriptorItem::ReportInfo&)data; + break; + + case HidReportDescriptorItem::kTagUsagePage: + sstr << (HidUsageAndPage::Page)data; + break; + + case HidReportDescriptorItem::kTagUsage: + case HidReportDescriptorItem::kTagReportId: + sstr << "0x" << std::hex << std::uppercase << data; + break; + + default: + sstr << data; + break; + } + if (pos == sstr.tellp()) { + std::string str = sstr.str(); + str.erase(str.end() - 2, str.end()); + os << str; + } else { + os << sstr.str() << ")"; + } + + return os; +} + +const char kIndentStep[] = " "; + +std::ostream& operator<<(std::ostream& os, + const HidReportDescriptor& descriptor) { + for (std::vector<linked_ptr<HidReportDescriptorItem> >::const_iterator + items_iter = descriptor.items().begin(); + items_iter != descriptor.items().end(); + ++items_iter) { + linked_ptr<HidReportDescriptorItem> item = *items_iter; + size_t indentLevel = item->GetDepth(); + for (size_t i = 0; i < indentLevel; i++) + os << kIndentStep; + os << *item.get() << std::endl; + } + return os; +} + +// See 'E.6 Report Descriptor (Keyboard)' +// in HID specifications (v1.11) +const uint8_t kKeyboard[] = { + 0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0, 0x29, + 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, + 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05, 0x75, 0x01, 0x05, + 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, + 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, + 0x07, 0x19, 0x00, 0x29, 0x65, 0x81, 0x00, 0xC0}; + +// See 'E.10 Report Descriptor (Mouse)' +// in HID specifications (v1.11) +const uint8_t kMouse[] = {0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, + 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, + 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, + 0x01, 0x75, 0x05, 0x81, 0x01, 0x05, 0x01, 0x09, 0x30, + 0x09, 0x31, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, + 0x02, 0x81, 0x06, 0xC0, 0xC0}; -// Logitech Unifying receiver descriptor const uint8_t kLogitechUnifyingReceiver[] = { - 0x06, 0x00, 0xFF, // Usage Page (Vendor) - 0x09, 0x01, // Usage (0x1) - 0xA1, 0x01, // Collection (Application) - 0x85, 0x10, // Report ID (0x10) - 0x75, 0x08, // Report Size (8) - 0x95, 0x06, // Report Count (6) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x09, 0x01, // Usage (0x1) - 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x09, 0x01, // Usage (0x1) - 0x91, 0x00, // Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0xC0, // End Collection - 0x06, 0x00, 0xFF, // Usage Page (Vendor) - 0x09, 0x02, // Usage (0x2) - 0xA1, 0x01, // Collection (Application) - 0x85, 0x11, // Report ID (0x11) - 0x75, 0x08, // Report Size (8) - 0x95, 0x13, // Report Count (19) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x09, 0x02, // Usage (0x2) - 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x09, 0x02, // Usage (0x2) - 0x91, 0x00, // Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0xC0, // End Collection - 0x06, 0x00, 0xFF, // Usage Page (Vendor) - 0x09, 0x04, // Usage (0x4) - 0xA1, 0x01, // Collection (Application) - 0x85, 0x20, // Report ID (0x20) - 0x75, 0x08, // Report Size (8) - 0x95, 0x0E, // Report Count (14) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x09, 0x41, // Usage (0x41) - 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x09, 0x41, // Usage (0x41) - 0x91, 0x00, // Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x85, 0x21, // Report ID (0x21) - 0x95, 0x1F, // Report Count (31) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x09, 0x42, // Usage (0x42) - 0x81, 0x00, // Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0x09, 0x42, // Usage (0x42) - 0x91, 0x00, // Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF) - 0xC0 // End Collection -}; + 0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x75, 0x08, + 0x95, 0x06, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x09, 0x01, 0x81, 0x00, + 0x09, 0x01, 0x91, 0x00, 0xC0, 0x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, + 0x01, 0x85, 0x11, 0x75, 0x08, 0x95, 0x13, 0x15, 0x00, 0x26, 0xFF, + 0x00, 0x09, 0x02, 0x81, 0x00, 0x09, 0x02, 0x91, 0x00, 0xC0, 0x06, + 0x00, 0xFF, 0x09, 0x04, 0xA1, 0x01, 0x85, 0x20, 0x75, 0x08, 0x95, + 0x0E, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x09, 0x41, 0x81, 0x00, 0x09, + 0x41, 0x91, 0x00, 0x85, 0x21, 0x95, 0x1F, 0x15, 0x00, 0x26, 0xFF, + 0x00, 0x09, 0x42, 0x81, 0x00, 0x09, 0x42, 0x91, 0x00, 0xC0}; } // namespace @@ -295,135 +415,199 @@ class HidReportDescriptorTest : public testing::Test { } public: - void ValidateDetails( - const std::vector<HidCollectionInfo>& expected_collections, - const int expected_max_input_report_size, - const int expected_max_output_report_size, - const int expected_max_feature_report_size, - const uint8_t* bytes, - size_t size) { + void ParseDescriptor(const std::string& expected, + const uint8_t* bytes, + size_t size) { descriptor_ = new HidReportDescriptor(bytes, size); - std::vector<HidCollectionInfo> actual_collections; - int actual_max_input_report_size; - int actual_max_output_report_size; - int actual_max_feature_report_size; - descriptor_->GetDetails(&actual_collections, - &actual_max_input_report_size, - &actual_max_output_report_size, - &actual_max_feature_report_size); - - ASSERT_EQ(expected_collections.size(), actual_collections.size()); - - std::vector<HidCollectionInfo>::const_iterator actual_collections_iter = - actual_collections.begin(); - std::vector<HidCollectionInfo>::const_iterator expected_collections_iter = - expected_collections.begin(); - - while (expected_collections_iter != expected_collections.end() && - actual_collections_iter != actual_collections.end()) { - HidCollectionInfo expected_collection = *expected_collections_iter; - HidCollectionInfo actual_collection = *actual_collections_iter; - - ASSERT_EQ(expected_collection.usage.usage_page, - actual_collection.usage.usage_page); - ASSERT_EQ(expected_collection.usage.usage, actual_collection.usage.usage); - ASSERT_THAT(actual_collection.report_ids, - ContainerEq(expected_collection.report_ids)); - - expected_collections_iter++; - actual_collections_iter++; + std::stringstream actual; + actual << *descriptor_; + + std::cout << "HID report descriptor:" << std::endl; + std::cout << actual.str(); + + // TODO(jracle@logitech.com): refactor string comparison in favor of + // testing individual fields. + ASSERT_EQ(expected, actual.str()); + } + + void GetTopLevelCollections(const std::vector<HidUsageAndPage>& expected, + const uint8_t* bytes, + size_t size) { + descriptor_ = new HidReportDescriptor(bytes, size); + + std::vector<HidUsageAndPage> actual; + descriptor_->GetTopLevelCollections(&actual); + + std::cout << "HID top-level collections:" << std::endl; + for (std::vector<HidUsageAndPage>::const_iterator iter = actual.begin(); + iter != actual.end(); + ++iter) { + std::cout << *iter << std::endl; } - ASSERT_EQ(expected_max_input_report_size, actual_max_input_report_size); - ASSERT_EQ(expected_max_output_report_size, actual_max_output_report_size); - ASSERT_EQ(expected_max_feature_report_size, actual_max_feature_report_size); + ASSERT_THAT(actual, ContainerEq(expected)); } private: HidReportDescriptor* descriptor_; }; -TEST_F(HidReportDescriptorTest, ValidateDetails_Digitizer) { - HidCollectionInfo digitizer; - digitizer.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageDigitizer); - digitizer.report_ids.insert(1); - digitizer.report_ids.insert(2); - digitizer.report_ids.insert(3); - HidCollectionInfo expected[] = {digitizer}; - ValidateDetails(std::vector<HidCollectionInfo>( - expected, expected + ARRAYSIZE_UNSAFE(expected)), - 7, - 0, - 0, - kDigitizer, - sizeof(kDigitizer)); +TEST_F(HidReportDescriptorTest, ParseDescriptor_Keyboard) { + const char expected[] = { + "Usage Page (Generic Desktop)\n" + "Usage (0x6)\n" + "Collection (Physical)\n" + " Usage Page (Keyboard)\n" + " Usage Minimum (224)\n" + " Usage Maximum (231)\n" + " Logical Minimum (0)\n" + " Logical Maximum (1)\n" + " Report Size (1)\n" + " Report Count (8)\n" + " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Report Count (1)\n" + " Report Size (8)\n" + " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Report Count (5)\n" + " Report Size (1)\n" + " Usage Page (Led)\n" + " Usage Minimum (1)\n" + " Usage Maximum (5)\n" + " Output (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Report Count (1)\n" + " Report Size (3)\n" + " Output (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Report Count (6)\n" + " Report Size (8)\n" + " Logical Minimum (0)\n" + " Logical Maximum (101)\n" + " Usage Page (Keyboard)\n" + " Usage Minimum (0)\n" + " Usage Maximum (101)\n" + " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + "End Collection\n"}; + + ParseDescriptor(std::string(expected), kKeyboard, sizeof(kKeyboard)); } -TEST_F(HidReportDescriptorTest, ValidateDetails_Keyboard) { - HidCollectionInfo keyboard; - keyboard.usage = HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop); - HidCollectionInfo expected[] = {keyboard}; - ValidateDetails(std::vector<HidCollectionInfo>( - expected, expected + ARRAYSIZE_UNSAFE(expected)), - 8, - 1, - 0, - kKeyboard, - sizeof(kKeyboard)); +TEST_F(HidReportDescriptorTest, TopLevelCollections_Keyboard) { + HidUsageAndPage expected[] = { + HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop)}; + + GetTopLevelCollections(std::vector<HidUsageAndPage>( + expected, expected + ARRAYSIZE_UNSAFE(expected)), + kKeyboard, + sizeof(kKeyboard)); } -TEST_F(HidReportDescriptorTest, ValidateDetails_Monitor) { - HidCollectionInfo monitor; - monitor.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageMonitor0); - monitor.report_ids.insert(1); - monitor.report_ids.insert(2); - monitor.report_ids.insert(3); - monitor.report_ids.insert(4); - monitor.report_ids.insert(5); - HidCollectionInfo expected[] = {monitor}; - ValidateDetails(std::vector<HidCollectionInfo>( - expected, expected + ARRAYSIZE_UNSAFE(expected)), - 0, - 0, - 244, - kMonitor, - sizeof(kMonitor)); +TEST_F(HidReportDescriptorTest, ParseDescriptor_Mouse) { + const char expected[] = { + "Usage Page (Generic Desktop)\n" + "Usage (0x2)\n" + "Collection (Physical)\n" + " Usage (0x1)\n" + " Collection (Physical)\n" + " Usage Page (Button)\n" + " Usage Minimum (1)\n" + " Usage Maximum (3)\n" + " Logical Minimum (0)\n" + " Logical Maximum (1)\n" + " Report Count (3)\n" + " Report Size (1)\n" + " Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Report Count (1)\n" + " Report Size (5)\n" + " Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Usage Page (Generic Desktop)\n" + " Usage (0x30)\n" + " Usage (0x31)\n" + " Logical Minimum (129)\n" + " Logical Maximum (127)\n" + " Report Size (8)\n" + " Report Count (2)\n" + " Input (Dat|Arr|Abs|NoWrp|Lin|Prf|NoNull|BitF)\n" + " End Collection\n" + "End Collection\n"}; + + ParseDescriptor(std::string(expected), kMouse, sizeof(kMouse)); } -TEST_F(HidReportDescriptorTest, ValidateDetails_Mouse) { - HidCollectionInfo mouse; - mouse.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop); - HidCollectionInfo expected[] = {mouse}; - ValidateDetails(std::vector<HidCollectionInfo>( - expected, expected + ARRAYSIZE_UNSAFE(expected)), - 3, - 0, - 0, - kMouse, - sizeof(kMouse)); +TEST_F(HidReportDescriptorTest, TopLevelCollections_Mouse) { + HidUsageAndPage expected[] = { + HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop)}; + + GetTopLevelCollections(std::vector<HidUsageAndPage>( + expected, expected + ARRAYSIZE_UNSAFE(expected)), + kMouse, + sizeof(kMouse)); } -TEST_F(HidReportDescriptorTest, ValidateDetails_LogitechUnifyingReceiver) { - HidCollectionInfo hidpp_short; - hidpp_short.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageVendor); - hidpp_short.report_ids.insert(0x10); - HidCollectionInfo hidpp_long; - hidpp_long.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageVendor); - hidpp_long.report_ids.insert(0x11); - HidCollectionInfo hidpp_dj; - hidpp_dj.usage = HidUsageAndPage(0x04, HidUsageAndPage::kPageVendor); - hidpp_dj.report_ids.insert(0x20); - hidpp_dj.report_ids.insert(0x21); - - HidCollectionInfo expected[] = {hidpp_short, hidpp_long, hidpp_dj}; - ValidateDetails(std::vector<HidCollectionInfo>( - expected, expected + ARRAYSIZE_UNSAFE(expected)), - 32, - 32, - 0, +TEST_F(HidReportDescriptorTest, ParseDescriptor_LogitechUnifyingReceiver) { + const char expected[] = { + "Usage Page (Vendor)\n" + "Usage (0x1)\n" + "Collection (Physical)\n" + " Report ID (0x10)\n" + " Report Size (8)\n" + " Report Count (6)\n" + " Logical Minimum (0)\n" + " Logical Maximum (255)\n" + " Usage (0x1)\n" + " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Usage (0x1)\n" + " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + "End Collection\n" + "Usage Page (Vendor)\n" + "Usage (0x2)\n" + "Collection (Physical)\n" + " Report ID (0x11)\n" + " Report Size (8)\n" + " Report Count (19)\n" + " Logical Minimum (0)\n" + " Logical Maximum (255)\n" + " Usage (0x2)\n" + " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Usage (0x2)\n" + " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + "End Collection\n" + "Usage Page (Vendor)\n" + "Usage (0x4)\n" + "Collection (Physical)\n" + " Report ID (0x20)\n" + " Report Size (8)\n" + " Report Count (14)\n" + " Logical Minimum (0)\n" + " Logical Maximum (255)\n" + " Usage (0x41)\n" + " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Usage (0x41)\n" + " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Report ID (0x21)\n" + " Report Count (31)\n" + " Logical Minimum (0)\n" + " Logical Maximum (255)\n" + " Usage (0x42)\n" + " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + " Usage (0x42)\n" + " Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" + "End Collection\n"}; + + ParseDescriptor(std::string(expected), kLogitechUnifyingReceiver, sizeof(kLogitechUnifyingReceiver)); } +TEST_F(HidReportDescriptorTest, TopLevelCollections_LogitechUnifyingReceiver) { + HidUsageAndPage expected[] = { + HidUsageAndPage(0x01, HidUsageAndPage::kPageVendor), + HidUsageAndPage(0x02, HidUsageAndPage::kPageVendor), + HidUsageAndPage(0x04, HidUsageAndPage::kPageVendor), }; + + GetTopLevelCollections(std::vector<HidUsageAndPage>( + expected, expected + ARRAYSIZE_UNSAFE(expected)), + kLogitechUnifyingReceiver, + sizeof(kLogitechUnifyingReceiver)); +} + } // namespace device |