diff options
author | reillyg <reillyg@chromium.org> | 2014-08-28 22:52:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-29 05:53:46 +0000 |
commit | f4dc9d143de2350fc4879c178059737997944016 (patch) | |
tree | de808301f613297af60b8ce5bdee43cc2b511264 /device/hid | |
parent | 3a05d24b124114e117c2d81592edbd14bbcf1b1c (diff) | |
download | chromium_src-f4dc9d143de2350fc4879c178059737997944016.zip chromium_src-f4dc9d143de2350fc4879c178059737997944016.tar.gz chromium_src-f4dc9d143de2350fc4879c178059737997944016.tar.bz2 |
Add more generic filters to the chrome.hid.getDevices API.
Instead of specifying each of the USB vendor and product ID pairs an
app has permission to open this API extension allows filtering of
devices by vendor and product IDs as well as HID usage pages and
usages. The 'vendorId' and 'productId' properties of GetDevicesOptions
are still supported for backwards compatibility.
BUG=
Review URL: https://codereview.chromium.org/514923002
Cr-Commit-Position: refs/heads/master@{#292577}
Diffstat (limited to 'device/hid')
-rw-r--r-- | device/hid/BUILD.gn | 2 | ||||
-rw-r--r-- | device/hid/hid.gyp | 2 | ||||
-rw-r--r-- | device/hid/hid_device_filter.cc | 89 | ||||
-rw-r--r-- | device/hid/hid_device_filter.h | 43 | ||||
-rw-r--r-- | device/hid/hid_device_filter_unittest.cc | 116 |
5 files changed, 252 insertions, 0 deletions
diff --git a/device/hid/BUILD.gn b/device/hid/BUILD.gn index edd3ecb..bc450db 100644 --- a/device/hid/BUILD.gn +++ b/device/hid/BUILD.gn @@ -16,6 +16,8 @@ source_set("hid") { "hid_connection_mac.h", "hid_connection_win.cc", "hid_connection_win.h", + "hid_device_filter.cc", + "hid_device_filter.h", "hid_device_info.cc", "hid_device_info.h", "hid_report_descriptor.cc", diff --git a/device/hid/hid.gyp b/device/hid/hid.gyp index 2db80fd..1c01ca1 100644 --- a/device/hid/hid.gyp +++ b/device/hid/hid.gyp @@ -26,6 +26,8 @@ 'hid_connection_mac.h', 'hid_connection_win.cc', 'hid_connection_win.h', + 'hid_device_filter.cc', + 'hid_device_filter.h', 'hid_device_info.cc', 'hid_device_info.h', 'hid_report_descriptor.cc', diff --git a/device/hid/hid_device_filter.cc b/device/hid/hid_device_filter.cc new file mode 100644 index 0000000..70ebcf4 --- /dev/null +++ b/device/hid/hid_device_filter.cc @@ -0,0 +1,89 @@ +// Copyright 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_device_filter.h" + +#include "device/hid/hid_device_info.h" + +namespace device { + +HidDeviceFilter::HidDeviceFilter() + : vendor_id_set_(false), + product_id_set_(false), + usage_page_set_(false), + usage_set_(false) { +} + +HidDeviceFilter::~HidDeviceFilter() { +} + +void HidDeviceFilter::SetVendorId(uint16_t vendor_id) { + vendor_id_set_ = true; + vendor_id_ = vendor_id; +} + +void HidDeviceFilter::SetProductId(uint16_t product_id) { + product_id_set_ = true; + product_id_ = product_id; +} + +void HidDeviceFilter::SetUsagePage(uint16_t usage_page) { + usage_page_set_ = true; + usage_page_ = usage_page; +} + +void HidDeviceFilter::SetUsage(uint16_t usage) { + usage_set_ = true; + usage_ = usage; +} + +bool HidDeviceFilter::Matches(const HidDeviceInfo& device_info) const { + if (vendor_id_set_) { + if (device_info.vendor_id != vendor_id_) { + return false; + } + + if (product_id_set_ && device_info.product_id != product_id_) { + return false; + } + } + + if (usage_page_set_) { + bool found_matching_collection = false; + for (std::vector<HidCollectionInfo>::const_iterator i = + device_info.collections.begin(); + i != device_info.collections.end() && !found_matching_collection; + ++i) { + const HidCollectionInfo& collection = *i; + if (collection.usage.usage_page != usage_page_) { + continue; + } + if (usage_set_ && collection.usage.usage != usage_) { + continue; + } + found_matching_collection = true; + } + if (!found_matching_collection) { + return false; + } + } + + return true; +} + +// static +bool HidDeviceFilter::MatchesAny( + const HidDeviceInfo& device_info, + const std::vector<HidDeviceFilter>& filters) { + for (std::vector<HidDeviceFilter>::const_iterator i = filters.begin(); + i != filters.end(); + ++i) { + if (i->Matches(device_info)) { + return true; + } + } + return false; +} + +} // namespace device diff --git a/device/hid/hid_device_filter.h b/device/hid/hid_device_filter.h new file mode 100644 index 0000000..a0abbb7 --- /dev/null +++ b/device/hid/hid_device_filter.h @@ -0,0 +1,43 @@ +// Copyright 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. + +#ifndef DEVICE_HID_HID_DEVICE_FILTER_H_ +#define DEVICE_HID_HID_DEVICE_FILTER_H_ + +#include <stdint.h> +#include <vector> + +namespace device { + +struct HidDeviceInfo; + +class HidDeviceFilter { + public: + HidDeviceFilter(); + ~HidDeviceFilter(); + + void SetVendorId(uint16_t vendor_id); + void SetProductId(uint16_t product_id); + void SetUsagePage(uint16_t usage_page); + void SetUsage(uint16_t usage); + + bool Matches(const HidDeviceInfo& device_info) const; + + static bool MatchesAny(const HidDeviceInfo& device_info, + const std::vector<HidDeviceFilter>& filters); + + private: + uint16_t vendor_id_; + uint16_t product_id_; + uint16_t usage_page_; + uint16_t usage_; + bool vendor_id_set_ : 1; + bool product_id_set_ : 1; + bool usage_page_set_ : 1; + bool usage_set_ : 1; +}; + +} // namespace device + +#endif // DEVICE_HID_HID_DEVICE_FILTER_H_ diff --git a/device/hid/hid_device_filter_unittest.cc b/device/hid/hid_device_filter_unittest.cc new file mode 100644 index 0000000..599dda4 --- /dev/null +++ b/device/hid/hid_device_filter_unittest.cc @@ -0,0 +1,116 @@ +// Copyright 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_device_filter.h" +#include "device/hid/hid_device_info.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace device { + +namespace { + +class HidFilterTest : public testing::Test { + public: + virtual void SetUp() OVERRIDE { + device_info_.vendor_id = 0x046d; + device_info_.product_id = 0xc31c; + + HidCollectionInfo collection; + collection.usage.usage_page = HidUsageAndPage::kPageKeyboard; + collection.usage.usage = 0x01; + device_info_.collections.push_back(collection); + } + + protected: + HidDeviceInfo device_info_; +}; + +TEST_F(HidFilterTest, MatchAny) { + HidDeviceFilter filter; + ASSERT_TRUE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchVendorId) { + HidDeviceFilter filter; + filter.SetVendorId(0x046d); + ASSERT_TRUE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchVendorIdNegative) { + HidDeviceFilter filter; + filter.SetVendorId(0x18d1); + ASSERT_FALSE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchProductId) { + HidDeviceFilter filter; + filter.SetVendorId(0x046d); + filter.SetProductId(0xc31c); + ASSERT_TRUE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchProductIdNegative) { + HidDeviceFilter filter; + filter.SetVendorId(0x046d); + filter.SetProductId(0x0801); + ASSERT_FALSE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchUsagePage) { + HidDeviceFilter filter; + filter.SetUsagePage(HidUsageAndPage::kPageKeyboard); + ASSERT_TRUE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchUsagePageNegative) { + HidDeviceFilter filter; + filter.SetUsagePage(HidUsageAndPage::kPageLed); + ASSERT_FALSE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchVendorAndUsagePage) { + HidDeviceFilter filter; + filter.SetVendorId(0x046d); + filter.SetUsagePage(HidUsageAndPage::kPageKeyboard); + ASSERT_TRUE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchUsageAndPage) { + HidDeviceFilter filter; + filter.SetUsagePage(HidUsageAndPage::kPageKeyboard); + filter.SetUsage(0x01); + ASSERT_TRUE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchUsageAndPageNegative) { + HidDeviceFilter filter; + filter.SetUsagePage(HidUsageAndPage::kPageKeyboard); + filter.SetUsage(0x02); + ASSERT_FALSE(filter.Matches(device_info_)); +} + +TEST_F(HidFilterTest, MatchEmptyFilterListNegative) { + std::vector<HidDeviceFilter> filters; + ASSERT_FALSE(HidDeviceFilter::MatchesAny(device_info_, filters)); +} + +TEST_F(HidFilterTest, MatchFilterList) { + std::vector<HidDeviceFilter> filters; + HidDeviceFilter filter; + filter.SetUsagePage(HidUsageAndPage::kPageKeyboard); + filters.push_back(filter); + ASSERT_TRUE(HidDeviceFilter::MatchesAny(device_info_, filters)); +} + +TEST_F(HidFilterTest, MatchFilterListNegative) { + std::vector<HidDeviceFilter> filters; + HidDeviceFilter filter; + filter.SetUsagePage(HidUsageAndPage::kPageLed); + filters.push_back(filter); + ASSERT_FALSE(HidDeviceFilter::MatchesAny(device_info_, filters)); +} + +} // namespace + +} // namespace device |