| Index: device/hid/hid_report_descriptor_unittest.cc
|
| diff --git a/device/hid/hid_report_descriptor_unittest.cc b/device/hid/hid_report_descriptor_unittest.cc
|
| index 0d258891081ee2f5874c6cde8a249c7e0b434937..619e682fed55bdde1c4ac3373600fcbfa7faa2be 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
|
|
|