Chromium Code Reviews| 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 |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9b8a9ad871a20d2ecd8ff531dd009df148e9784d |
| --- /dev/null |
| +++ b/device/hid/hid_report_descriptor_unittest.cc |
| @@ -0,0 +1,361 @@ |
| +// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "device/hid/hid_report_descriptor.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +using namespace testing; |
| + |
| +namespace device { |
| + |
| +namespace { |
| + |
| + // 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 |
| + }; |
| + |
| + 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 |
| + }; |
| + |
| +} // namespace |
| + |
| +class HidReportDescriptorTest : public testing::Test { |
| + protected: |
| + virtual void SetUp() OVERRIDE { |
| + descriptor_ = NULL; |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { |
| + if (descriptor_) { |
| + delete descriptor_; |
| + } |
| + } |
| + |
| + public: |
| + void ParseDescriptor(const std::string& parsed_expected, |
| + const uint8_t *bytes, |
| + size_t size) { |
| + |
| + descriptor_ = new HidReportDescriptor(bytes, size); |
| + |
| + std::stringstream parsed_actual; |
| + parsed_actual << *descriptor_; |
| + |
| + std::cout << "HID report descriptor:" << std::endl; |
| + std::cout << *descriptor_; |
| + |
| + ASSERT_EQ(parsed_expected, parsed_actual.str()); |
| + } |
| + |
| + void GetTopLevelCollections( |
| + const std::vector<HidUsageAndPage>& tlcs_expected, |
| + const uint8_t *bytes, |
| + size_t size) { |
| + |
| + descriptor_ = new HidReportDescriptor(bytes, size); |
| + |
| + std::vector<HidUsageAndPage> tlcs_actual |
| + = descriptor_->topLevelCollections(); |
| + |
| + std::cout << "HID top-level collections:" << std::endl; |
| + for (std::vector<HidUsageAndPage>::const_iterator |
| + tlcs_iter = tlcs_actual.begin(); |
| + tlcs_iter != tlcs_actual.end(); |
| + ++tlcs_iter) { |
| + std::cout << *tlcs_iter << std::endl; |
| + } |
| + |
| + ASSERT_THAT(tlcs_actual, ContainerEq(tlcs_expected)); |
| + } |
| + |
| + private: |
| + HidReportDescriptor* descriptor_; |
| +}; |
| + |
| +TEST_F(HidReportDescriptorTest, ParseDescriptor_Keyboard) { |
| + |
| + const char parsed_expected[] = { |
| + "Usage Page (Generic Desktop)\n" |
| + "Usage (0x6)\n" |
| + "Collection (Physical)\n" |
| + " Usage Page (Keyboard)\n" |
| + " Usage Minimum (0xE0)\n" |
| + " Usage Maximum (0xE7)\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 (0x1)\n" |
| + " Usage Maximum (0x5)\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 (0x0)\n" |
| + " Usage Maximum (0x65)\n" |
| + " Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)\n" |
| + "End Collection\n" |
| + }; |
| + |
| + ParseDescriptor(std::string(parsed_expected), |
| + kKeyboard, |
| + sizeof(kKeyboard)); |
| +} |
| + |
| +TEST_F(HidReportDescriptorTest, TopLevelCollections_Keyboard) { |
| + |
| + HidUsageAndPage tlcs_expected[] = { |
| + HidUsageAndPage(HidUsageAndPage::kPageGenericDesktop, 0x06) |
| + }; |
| + |
| + GetTopLevelCollections(std::vector<HidUsageAndPage>( |
| + tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| + kKeyboard, |
| + sizeof(kKeyboard)); |
| +} |
| + |
| +TEST_F(HidReportDescriptorTest, ParseDescriptor_Mouse) { |
| + |
| + const char parsed_expected[] = { |
| + "Usage Page (Generic Desktop)\n" |
| + "Usage (0x2)\n" |
| + "Collection (Physical)\n" |
| + " Usage (0x1)\n" |
| + " Collection (Physical)\n" |
| + " Usage Page (Button)\n" |
| + " Usage Minimum (0x1)\n" |
| + " Usage Maximum (0x3)\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(parsed_expected), |
| + kMouse, |
| + sizeof(kMouse)); |
| +} |
| + |
| +TEST_F(HidReportDescriptorTest, TopLevelCollections_Mouse) { |
| + |
| + HidUsageAndPage tlcs_expected[] = { |
| + HidUsageAndPage(HidUsageAndPage::kPageGenericDesktop, 0x02) |
| + }; |
| + |
| + GetTopLevelCollections(std::vector<HidUsageAndPage>( |
| + tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| + kMouse, |
| + sizeof(kMouse)); |
| +} |
| + |
| +TEST_F(HidReportDescriptorTest, ParseDescriptor_LogitechUnifyingReceiver) { |
| + |
| + const char parsed_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(parsed_expected), |
| + kLogitechUnifyingReceiver, |
| + sizeof(kLogitechUnifyingReceiver)); |
| +} |
| + |
| +TEST_F(HidReportDescriptorTest, TopLevelCollections_LogitechUnifyingReceiver) { |
| + |
|
Ken Rockot(use gerrit already)
2014/04/15 17:53:38
nit: No need for vertical whitespace at the top of
|
| + HidUsageAndPage tlcs_expected[] = { |
| + HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x01), |
| + HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x02), |
| + HidUsageAndPage(HidUsageAndPage::kPageVendor, 0x04), |
| + }; |
| + |
| + GetTopLevelCollections(std::vector<HidUsageAndPage>( |
| + tlcs_expected, tlcs_expected + ARRAYSIZE_UNSAFE(tlcs_expected)), |
| + kLogitechUnifyingReceiver, |
| + sizeof(kLogitechUnifyingReceiver)); |
| +} |
| + |
| +} // namespace device |