summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
Diffstat (limited to 'device')
-rw-r--r--device/device_tests.gyp1
-rw-r--r--device/hid/BUILD.gn2
-rw-r--r--device/hid/hid.gyp2
-rw-r--r--device/hid/hid_device_filter.cc89
-rw-r--r--device/hid/hid_device_filter.h43
-rw-r--r--device/hid/hid_device_filter_unittest.cc116
6 files changed, 253 insertions, 0 deletions
diff --git a/device/device_tests.gyp b/device/device_tests.gyp
index 7e913e6..6b5a59b 100644
--- a/device/device_tests.gyp
+++ b/device/device_tests.gyp
@@ -44,6 +44,7 @@
'usb/usb_ids_unittest.cc',
'usb/usb_service_unittest.cc',
'hid/hid_connection_unittest.cc',
+ 'hid/hid_device_filter_unittest.cc',
'hid/hid_report_descriptor_unittest.cc',
'hid/hid_service_unittest.cc',
'hid/input_service_linux_unittest.cc',
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