Home | History | Annotate | Download | only in hid
      1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <sstream>
      6 
      7 #include "device/hid/hid_report_descriptor.h"
      8 #include "testing/gmock/include/gmock/gmock.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 using namespace testing;
     12 
     13 namespace device {
     14 
     15 namespace {
     16 
     17 // Digitizer descriptor from HID descriptor tool
     18 // http://www.usb.org/developers/hidpage/dt2_4.zip
     19 const uint8_t kDigitizer[] = {
     20     0x05, 0x0d,        // Usage Page (Digitizer)
     21     0x09, 0x01,        // Usage (0x1)
     22     0xa1, 0x01,        // Collection (Application)
     23     0x85, 0x01,        //  Report ID (0x1)
     24     0x09, 0x21,        //  Usage (0x21)
     25     0xa1, 0x00,        //  Collection (Physical)
     26     0x05, 0x01,        //   Usage Page (Generic Desktop)
     27     0x09, 0x30,        //   Usage (0x30)
     28     0x09, 0x31,        //   Usage (0x31)
     29     0x75, 0x10,        //   Report Size (16)
     30     0x95, 0x02,        //   Report Count (2)
     31     0x15, 0x00,        //   Logical Minimum (0)
     32     0x26, 0xe0, 0x2e,  //   Logical Maximum (12000)
     33     0x35, 0x00,        //   Physical Minimum (0)
     34     0x45, 0x0c,        //   Physical Maximum (12)
     35     0x65, 0x13,        //   Unit (19)
     36     0x55, 0x00,        //   Unit Exponent (0)
     37     0xa4,              //   Push
     38     0x81, 0x02,        //   Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
     39     0x05, 0x0d,        //   Usage Page (Digitizer)
     40     0x09, 0x32,        //   Usage (0x32)
     41     0x09, 0x44,        //   Usage (0x44)
     42     0x09, 0x42,        //   Usage (0x42)
     43     0x15, 0x00,        //   Logical Minimum (0)
     44     0x25, 0x01,        //   Logical Maximum (1)
     45     0x35, 0x00,        //   Physical Minimum (0)
     46     0x45, 0x01,        //   Physical Maximum (1)
     47     0x75, 0x01,        //   Report Size (1)
     48     0x95, 0x03,        //   Report Count (3)
     49     0x65, 0x00,        //   Unit (0)
     50     0x81, 0x02,        //   Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
     51     0x95, 0x01,        //   Report Count (1)
     52     0x75, 0x05,        //   Report Size (5)
     53     0x81, 0x03,        //   Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
     54     0xc0,              //  End Collection
     55     0x85, 0x02,        //  Report ID (0x2)
     56     0x09, 0x20,        //  Usage (0x20)
     57     0xa1, 0x00,        //  Collection (Physical)
     58     0xb4,              //   Pop
     59     0xa4,              //   Push
     60     0x09, 0x30,        //   Usage (0x30)
     61     0x09, 0x31,        //   Usage (0x31)
     62     0x81, 0x02,        //   Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
     63     0x05, 0x0d,        //   Usage Page (Digitizer)
     64     0x09, 0x32,        //   Usage (0x32)
     65     0x15, 0x00,        //   Logical Minimum (0)
     66     0x25, 0x01,        //   Logical Maximum (1)
     67     0x35, 0x00,        //   Physical Minimum (0)
     68     0x45, 0x01,        //   Physical Maximum (1)
     69     0x65, 0x00,        //   Unit (0)
     70     0x75, 0x01,        //   Report Size (1)
     71     0x81, 0x02,        //   Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
     72     0x05, 0x09,        //   Usage Page (Button)
     73     0x19, 0x00,        //   Usage Minimum (0)
     74     0x29, 0x10,        //   Usage Maximum (16)
     75     0x25, 0x10,        //   Logical Maximum (16)
     76     0x75, 0x05,        //   Report Size (5)
     77     0x81, 0x40,        //   Input (Dat|Var|Rel|NoWrp|Lin|Prf|Null|BitF)
     78     0x75, 0x02,        //   Report Size (2)
     79     0x81, 0x01,        //   Input (Con|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
     80     0xc0,              //  End Collection
     81     0x85, 0x03,        //  Report ID (0x3)
     82     0x05, 0x0d,        //  Usage Page (Digitizer)
     83     0x09, 0x20,        //  Usage (0x20)
     84     0xa1, 0x00,        //  Collection (Physical)
     85     0xb4,              //   Pop
     86     0x09, 0x30,        //   Usage (0x30)
     87     0x09, 0x31,        //   Usage (0x31)
     88     0x81, 0x02,        //   Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
     89     0x05, 0x0d,        //   Usage Page (Digitizer)
     90     0x09, 0x32,        //   Usage (0x32)
     91     0x09, 0x44,        //   Usage (0x44)
     92     0x75, 0x01,        //   Report Size (1)
     93     0x15, 0x00,        //   Logical Minimum (0)
     94     0x25, 0x01,        //   Logical Maximum (1)
     95     0x35, 0x00,        //   Physical Minimum (0)
     96     0x45, 0x01,        //   Physical Maximum (1)
     97     0x65, 0x00,        //   Unit (0)
     98     0x81, 0x02,        //   Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
     99     0x95, 0x06,        //   Report Count (6)
    100     0x81, 0x03,        //   Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    101     0x09, 0x30,        //   Usage (0x30)
    102     0x15, 0x00,        //   Logical Minimum (0)
    103     0x25, 0x7f,        //   Logical Maximum (127)
    104     0x35, 0x00,        //   Physical Minimum (0)
    105     0x45, 0x2d,        //   Physical Maximum (45)
    106     0x67, 0x11, 0xe1,  //   Unit (57617)
    107     0x00, 0x00,        //   Default
    108     0x55, 0x04,        //   Unit Exponent (4)
    109     0x75, 0x08,        //   Report Size (8)
    110     0x95, 0x01,        //   Report Count (1)
    111     0x81, 0x12,        //   Input (Dat|Arr|Rel|NoWrp|NoLin|Prf|NoNull|BitF)
    112     0xc0,              //  End Collection
    113     0xc0               // End Collection
    114 };
    115 
    116 // Keyboard descriptor from HID descriptor tool
    117 // http://www.usb.org/developers/hidpage/dt2_4.zip
    118 const uint8_t kKeyboard[] = {
    119     0x05, 0x01,  // Usage Page (Generic Desktop)
    120     0x09, 0x06,  // Usage (0x6)
    121     0xa1, 0x01,  // Collection (Application)
    122     0x05, 0x07,  //  Usage Page (Keyboard)
    123     0x19, 0xe0,  //  Usage Minimum (224)
    124     0x29, 0xe7,  //  Usage Maximum (231)
    125     0x15, 0x00,  //  Logical Minimum (0)
    126     0x25, 0x01,  //  Logical Maximum (1)
    127     0x75, 0x01,  //  Report Size (1)
    128     0x95, 0x08,  //  Report Count (8)
    129     0x81, 0x02,  //  Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    130     0x95, 0x01,  //  Report Count (1)
    131     0x75, 0x08,  //  Report Size (8)
    132     0x81, 0x03,  //  Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    133     0x95, 0x05,  //  Report Count (5)
    134     0x75, 0x01,  //  Report Size (1)
    135     0x05, 0x08,  //  Usage Page (Led)
    136     0x19, 0x01,  //  Usage Minimum (1)
    137     0x29, 0x05,  //  Usage Maximum (5)
    138     0x91, 0x02,  //  Output (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    139     0x95, 0x01,  //  Report Count (1)
    140     0x75, 0x03,  //  Report Size (3)
    141     0x91, 0x03,  //  Output (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    142     0x95, 0x06,  //  Report Count (6)
    143     0x75, 0x08,  //  Report Size (8)
    144     0x15, 0x00,  //  Logical Minimum (0)
    145     0x25, 0x65,  //  Logical Maximum (101)
    146     0x05, 0x07,  //  Usage Page (Keyboard)
    147     0x19, 0x00,  //  Usage Minimum (0)
    148     0x29, 0x65,  //  Usage Maximum (101)
    149     0x81, 0x00,  //  Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    150     0xc0         // End Collection
    151 };
    152 
    153 // Monitor descriptor from HID descriptor tool
    154 // http://www.usb.org/developers/hidpage/dt2_4.zip
    155 const uint8_t kMonitor[] = {
    156     0x05, 0x80,        // Usage Page (Monitor 0)
    157     0x09, 0x01,        // Usage (0x1)
    158     0xa1, 0x01,        // Collection (Application)
    159     0x85, 0x01,        //  Report ID (0x1)
    160     0x15, 0x00,        //  Logical Minimum (0)
    161     0x26, 0xff, 0x00,  //  Logical Maximum (255)
    162     0x75, 0x08,        //  Report Size (8)
    163     0x95, 0x80,        //  Report Count (128)
    164     0x09, 0x02,        //  Usage (0x2)
    165     0xb2, 0x02, 0x01,  //  Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|Buff)
    166     0x85, 0x02,        //  Report ID (0x2)
    167     0x95, 0xf3,        //  Report Count (243)
    168     0x09, 0x03,        //  Usage (0x3)
    169     0xb2, 0x02, 0x01,  //  Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|Buff)
    170     0x85, 0x03,        //  Report ID (0x3)
    171     0x05, 0x82,        //  Usage Page (Monitor 2)
    172     0x95, 0x01,        //  Report Count (1)
    173     0x75, 0x10,        //  Report Size (16)
    174     0x26, 0xc8, 0x00,  //  Logical Maximum (200)
    175     0x09, 0x10,        //  Usage (0x10)
    176     0xb1, 0x02,        //  Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    177     0x85, 0x04,        //  Report ID (0x4)
    178     0x25, 0x64,        //  Logical Maximum (100)
    179     0x09, 0x12,        //  Usage (0x12)
    180     0xb1, 0x02,        //  Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    181     0x95, 0x06,        //  Report Count (6)
    182     0x26, 0xff, 0x00,  //  Logical Maximum (255)
    183     0x09, 0x16,        //  Usage (0x16)
    184     0x09, 0x18,        //  Usage (0x18)
    185     0x09, 0x1a,        //  Usage (0x1A)
    186     0x09, 0x6c,        //  Usage (0x6C)
    187     0x09, 0x6e,        //  Usage (0x6E)
    188     0x09, 0x70,        //  Usage (0x70)
    189     0xb1, 0x02,        //  Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    190     0x85, 0x05,        //  Report ID (0x5)
    191     0x25, 0x7f,        //  Logical Maximum (127)
    192     0x09, 0x20,        //  Usage (0x20)
    193     0x09, 0x22,        //  Usage (0x22)
    194     0x09, 0x30,        //  Usage (0x30)
    195     0x09, 0x32,        //  Usage (0x32)
    196     0x09, 0x42,        //  Usage (0x42)
    197     0x09, 0x44,        //  Usage (0x44)
    198     0xb1, 0x02,        //  Feature (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    199     0xc0               // End Collection
    200 };
    201 
    202 // Mouse descriptor from HID descriptor tool
    203 // http://www.usb.org/developers/hidpage/dt2_4.zip
    204 const uint8_t kMouse[] = {
    205     0x05, 0x01,  // Usage Page (Generic Desktop)
    206     0x09, 0x02,  // Usage (0x2)
    207     0xa1, 0x01,  // Collection (Application)
    208     0x09, 0x01,  //  Usage (0x1)
    209     0xa1, 0x00,  //  Collection (Physical)
    210     0x05, 0x09,  //   Usage Page (Button)
    211     0x19, 0x01,  //   Usage Minimum (1)
    212     0x29, 0x03,  //   Usage Maximum (3)
    213     0x15, 0x00,  //   Logical Minimum (0)
    214     0x25, 0x01,  //   Logical Maximum (1)
    215     0x95, 0x03,  //   Report Count (3)
    216     0x75, 0x01,  //   Report Size (1)
    217     0x81, 0x02,  //   Input (Dat|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    218     0x95, 0x01,  //   Report Count (1)
    219     0x75, 0x05,  //   Report Size (5)
    220     0x81, 0x03,  //   Input (Con|Arr|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    221     0x05, 0x01,  //   Usage Page (Generic Desktop)
    222     0x09, 0x30,  //   Usage (0x30)
    223     0x09, 0x31,  //   Usage (0x31)
    224     0x15, 0x81,  //   Logical Minimum (129)
    225     0x25, 0x7f,  //   Logical Maximum (127)
    226     0x75, 0x08,  //   Report Size (8)
    227     0x95, 0x02,  //   Report Count (2)
    228     0x81, 0x06,  //   Input (Dat|Arr|Abs|NoWrp|Lin|Prf|NoNull|BitF)
    229     0xc0,        //  End Collection
    230     0xc0         // End Collection
    231 };
    232 
    233 // Logitech Unifying receiver descriptor
    234 const uint8_t kLogitechUnifyingReceiver[] = {
    235     0x06, 0x00, 0xFF,  // Usage Page (Vendor)
    236     0x09, 0x01,        // Usage (0x1)
    237     0xA1, 0x01,        // Collection (Application)
    238     0x85, 0x10,        //  Report ID (0x10)
    239     0x75, 0x08,        //  Report Size (8)
    240     0x95, 0x06,        //  Report Count (6)
    241     0x15, 0x00,        //  Logical Minimum (0)
    242     0x26, 0xFF, 0x00,  //  Logical Maximum (255)
    243     0x09, 0x01,        //  Usage (0x1)
    244     0x81, 0x00,        //  Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    245     0x09, 0x01,        //  Usage (0x1)
    246     0x91, 0x00,        //  Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    247     0xC0,              // End Collection
    248     0x06, 0x00, 0xFF,  // Usage Page (Vendor)
    249     0x09, 0x02,        // Usage (0x2)
    250     0xA1, 0x01,        // Collection (Application)
    251     0x85, 0x11,        //  Report ID (0x11)
    252     0x75, 0x08,        //  Report Size (8)
    253     0x95, 0x13,        //  Report Count (19)
    254     0x15, 0x00,        //  Logical Minimum (0)
    255     0x26, 0xFF, 0x00,  //  Logical Maximum (255)
    256     0x09, 0x02,        //  Usage (0x2)
    257     0x81, 0x00,        //  Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    258     0x09, 0x02,        //  Usage (0x2)
    259     0x91, 0x00,        //  Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    260     0xC0,              // End Collection
    261     0x06, 0x00, 0xFF,  // Usage Page (Vendor)
    262     0x09, 0x04,        // Usage (0x4)
    263     0xA1, 0x01,        // Collection (Application)
    264     0x85, 0x20,        //  Report ID (0x20)
    265     0x75, 0x08,        //  Report Size (8)
    266     0x95, 0x0E,        //  Report Count (14)
    267     0x15, 0x00,        //  Logical Minimum (0)
    268     0x26, 0xFF, 0x00,  //  Logical Maximum (255)
    269     0x09, 0x41,        //  Usage (0x41)
    270     0x81, 0x00,        //  Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    271     0x09, 0x41,        //  Usage (0x41)
    272     0x91, 0x00,        //  Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    273     0x85, 0x21,        //  Report ID (0x21)
    274     0x95, 0x1F,        //  Report Count (31)
    275     0x15, 0x00,        //  Logical Minimum (0)
    276     0x26, 0xFF, 0x00,  //  Logical Maximum (255)
    277     0x09, 0x42,        //  Usage (0x42)
    278     0x81, 0x00,        //  Input (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    279     0x09, 0x42,        //  Usage (0x42)
    280     0x91, 0x00,        //  Output (Dat|Var|Rel|NoWrp|Lin|Prf|NoNull|BitF)
    281     0xC0               // End Collection
    282 };
    283 
    284 }  // namespace
    285 
    286 class HidReportDescriptorTest : public testing::Test {
    287 
    288  protected:
    289   virtual void SetUp() OVERRIDE { descriptor_ = NULL; }
    290 
    291   virtual void TearDown() OVERRIDE {
    292     if (descriptor_) {
    293       delete descriptor_;
    294     }
    295   }
    296 
    297  public:
    298   void ValidateDetails(
    299       const std::vector<HidCollectionInfo>& expected_collections,
    300       const bool expected_has_report_id,
    301       const uint16_t expected_max_input_report_size,
    302       const uint16_t expected_max_output_report_size,
    303       const uint16_t expected_max_feature_report_size,
    304       const uint8_t* bytes,
    305       size_t size) {
    306     descriptor_ = new HidReportDescriptor(bytes, size);
    307 
    308     std::vector<HidCollectionInfo> actual_collections;
    309     bool actual_has_report_id;
    310     uint16_t actual_max_input_report_size;
    311     uint16_t actual_max_output_report_size;
    312     uint16_t actual_max_feature_report_size;
    313     descriptor_->GetDetails(&actual_collections,
    314                             &actual_has_report_id,
    315                             &actual_max_input_report_size,
    316                             &actual_max_output_report_size,
    317                             &actual_max_feature_report_size);
    318 
    319     ASSERT_EQ(expected_collections.size(), actual_collections.size());
    320 
    321     std::vector<HidCollectionInfo>::const_iterator actual_collections_iter =
    322         actual_collections.begin();
    323     std::vector<HidCollectionInfo>::const_iterator expected_collections_iter =
    324         expected_collections.begin();
    325 
    326     while (expected_collections_iter != expected_collections.end() &&
    327            actual_collections_iter != actual_collections.end()) {
    328       HidCollectionInfo expected_collection = *expected_collections_iter;
    329       HidCollectionInfo actual_collection = *actual_collections_iter;
    330 
    331       ASSERT_EQ(expected_collection.usage.usage_page,
    332                 actual_collection.usage.usage_page);
    333       ASSERT_EQ(expected_collection.usage.usage, actual_collection.usage.usage);
    334       ASSERT_THAT(actual_collection.report_ids,
    335                   ContainerEq(expected_collection.report_ids));
    336 
    337       expected_collections_iter++;
    338       actual_collections_iter++;
    339     }
    340 
    341     ASSERT_EQ(expected_has_report_id, actual_has_report_id);
    342     ASSERT_EQ(expected_max_input_report_size, actual_max_input_report_size);
    343     ASSERT_EQ(expected_max_output_report_size, actual_max_output_report_size);
    344     ASSERT_EQ(expected_max_feature_report_size, actual_max_feature_report_size);
    345   }
    346 
    347  private:
    348   HidReportDescriptor* descriptor_;
    349 };
    350 
    351 TEST_F(HidReportDescriptorTest, ValidateDetails_Digitizer) {
    352   HidCollectionInfo digitizer;
    353   digitizer.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageDigitizer);
    354   digitizer.report_ids.insert(1);
    355   digitizer.report_ids.insert(2);
    356   digitizer.report_ids.insert(3);
    357   HidCollectionInfo expected[] = {digitizer};
    358   ValidateDetails(std::vector<HidCollectionInfo>(
    359                       expected, expected + ARRAYSIZE_UNSAFE(expected)),
    360                   true,
    361                   6,
    362                   0,
    363                   0,
    364                   kDigitizer,
    365                   sizeof(kDigitizer));
    366 }
    367 
    368 TEST_F(HidReportDescriptorTest, ValidateDetails_Keyboard) {
    369   HidCollectionInfo keyboard;
    370   keyboard.usage = HidUsageAndPage(0x06, HidUsageAndPage::kPageGenericDesktop);
    371   HidCollectionInfo expected[] = {keyboard};
    372   ValidateDetails(std::vector<HidCollectionInfo>(
    373                       expected, expected + ARRAYSIZE_UNSAFE(expected)),
    374                   false,
    375                   8,
    376                   1,
    377                   0,
    378                   kKeyboard,
    379                   sizeof(kKeyboard));
    380 }
    381 
    382 TEST_F(HidReportDescriptorTest, ValidateDetails_Monitor) {
    383   HidCollectionInfo monitor;
    384   monitor.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageMonitor0);
    385   monitor.report_ids.insert(1);
    386   monitor.report_ids.insert(2);
    387   monitor.report_ids.insert(3);
    388   monitor.report_ids.insert(4);
    389   monitor.report_ids.insert(5);
    390   HidCollectionInfo expected[] = {monitor};
    391   ValidateDetails(std::vector<HidCollectionInfo>(
    392                       expected, expected + ARRAYSIZE_UNSAFE(expected)),
    393                   true,
    394                   0,
    395                   0,
    396                   243,
    397                   kMonitor,
    398                   sizeof(kMonitor));
    399 }
    400 
    401 TEST_F(HidReportDescriptorTest, ValidateDetails_Mouse) {
    402   HidCollectionInfo mouse;
    403   mouse.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageGenericDesktop);
    404   HidCollectionInfo expected[] = {mouse};
    405   ValidateDetails(std::vector<HidCollectionInfo>(
    406                       expected, expected + ARRAYSIZE_UNSAFE(expected)),
    407                   false,
    408                   3,
    409                   0,
    410                   0,
    411                   kMouse,
    412                   sizeof(kMouse));
    413 }
    414 
    415 TEST_F(HidReportDescriptorTest, ValidateDetails_LogitechUnifyingReceiver) {
    416   HidCollectionInfo hidpp_short;
    417   hidpp_short.usage = HidUsageAndPage(0x01, HidUsageAndPage::kPageVendor);
    418   hidpp_short.report_ids.insert(0x10);
    419   HidCollectionInfo hidpp_long;
    420   hidpp_long.usage = HidUsageAndPage(0x02, HidUsageAndPage::kPageVendor);
    421   hidpp_long.report_ids.insert(0x11);
    422   HidCollectionInfo hidpp_dj;
    423   hidpp_dj.usage = HidUsageAndPage(0x04, HidUsageAndPage::kPageVendor);
    424   hidpp_dj.report_ids.insert(0x20);
    425   hidpp_dj.report_ids.insert(0x21);
    426 
    427   HidCollectionInfo expected[] = {hidpp_short, hidpp_long, hidpp_dj};
    428   ValidateDetails(std::vector<HidCollectionInfo>(
    429                       expected, expected + ARRAYSIZE_UNSAFE(expected)),
    430                   true,
    431                   31,
    432                   31,
    433                   0,
    434                   kLogitechUnifyingReceiver,
    435                   sizeof(kLogitechUnifyingReceiver));
    436 }
    437 
    438 }  // namespace device
    439