diff options
author | jracle@logitech.com <jracle@logitech.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-03 02:53:23 +0000 |
---|---|---|
committer | jracle@logitech.com <jracle@logitech.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-03 02:53:23 +0000 |
commit | 9ff38235dcea4a3a95e25b602c347f5646bdf4bb (patch) | |
tree | 8b3c0b46ea6699591de7e55e760b73b4753610ae /device/hid/hid_report_descriptor_unittest.cc | |
parent | 5a43fe6ffbd21cc9a494fa6ed841f877fa09e243 (diff) | |
download | chromium_src-9ff38235dcea4a3a95e25b602c347f5646bdf4bb.zip chromium_src-9ff38235dcea4a3a95e25b602c347f5646bdf4bb.tar.gz chromium_src-9ff38235dcea4a3a95e25b602c347f5646bdf4bb.tar.bz2 |
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
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281133 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, 370 insertions, 554 deletions
diff --git a/device/hid/hid_report_descriptor_unittest.cc b/device/hid/hid_report_descriptor_unittest.cc index 0d25889..619e682 100644 --- a/device/hid/hid_report_descriptor_unittest.cc +++ b/device/hid/hid_report_descriptor_unittest.cc @@ -14,392 +14,272 @@ namespace device { namespace { -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; -} - -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; -} - -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; - } - - 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; -} +// 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 +}; -// See 'E.6 Report Descriptor (Keyboard)' -// in HID specifications (v1.11) +// Keyboard descriptor from HID descriptor tool +// http://www.usb.org/developers/hidpage/dt2_4.zip 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}; + 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 +}; -// 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}; +// 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 +}; +// 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 +}; + +// Logitech Unifying receiver descriptor const uint8_t kLogitechUnifyingReceiver[] = { - 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}; + 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 +}; } // namespace @@ -415,199 +295,135 @@ class HidReportDescriptorTest : public testing::Test { } public: - void ParseDescriptor(const std::string& expected, - const uint8_t* bytes, - size_t size) { + 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) { descriptor_ = new HidReportDescriptor(bytes, size); - 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; + 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++; } - ASSERT_THAT(actual, ContainerEq(expected)); + 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); } private: HidReportDescriptor* descriptor_; }; -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_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, TopLevelCollections_Keyboard) { - HidUsageAndPage expected[] = { - HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop)}; - - GetTopLevelCollections(std::vector<HidUsageAndPage>( - expected, expected + ARRAYSIZE_UNSAFE(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, 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_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, TopLevelCollections_Mouse) { - HidUsageAndPage expected[] = { - HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop)}; - - GetTopLevelCollections(std::vector<HidUsageAndPage>( - expected, expected + ARRAYSIZE_UNSAFE(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, 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), +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, 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 |