summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/chrome_browser_extensions.gypi1
-rw-r--r--device/device.gyp36
-rw-r--r--device/usb/OWNERS2
-rw-r--r--device/usb/usb_ids.cc58
-rw-r--r--device/usb/usb_ids.h58
-rw-r--r--device/usb/usb_ids_unittest.cc31
-rw-r--r--tools/usb_ids/usb_ids.py110
7 files changed, 296 insertions, 0 deletions
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 2fc5943..5d4efe1 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -31,6 +31,7 @@
'../content/content.gyp:content_browser',
'../crypto/crypto.gyp:crypto',
'../device/device.gyp:device_bluetooth',
+ '../device/device.gyp:device_usb',
'../net/net.gyp:net',
'../skia/skia.gyp:skia',
'../sync/sync.gyp:sync_notifier',
diff --git a/device/device.gyp b/device/device.gyp
index 75902fc..08cac92 100644
--- a/device/device.gyp
+++ b/device/device.gyp
@@ -71,11 +71,46 @@
],
},
{
+ 'target_name': 'device_usb',
+ 'type': 'static_library',
+ 'sources': [
+ 'usb/usb_ids.cc',
+ 'usb/usb_ids.h',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_usb_ids',
+ 'variables': {
+ 'usb_ids_path%': '<(DEPTH)/third_party/usb_ids/usb.ids',
+ 'usb_ids_py_path': '<(DEPTH)/tools/usb_ids/usb_ids.py',
+ },
+ 'inputs': [
+ '<(usb_ids_path)',
+ '<(usb_ids_py_path)',
+ ],
+ 'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/device/usb/usb_ids_gen.cc',
+ ],
+ 'action': [
+ 'python',
+ '<(usb_ids_py_path)',
+ '-i', '<(usb_ids_path)',
+ '-o', '<@(_outputs)',
+ ],
+ 'process_outputs_as_sources': 1,
+ },
+ ],
+ },
+ {
'target_name': 'device_unittests',
'type': '<(gtest_target_type)',
'dependencies': [
'device_bluetooth',
'device_bluetooth_mocks',
+ 'device_usb',
'../base/base.gyp:test_support_base',
'../content/content.gyp:test_support_content',
'../testing/gmock.gyp:gmock',
@@ -90,6 +125,7 @@
'test/device_test_suite.cc',
'test/device_test_suite.h',
'test/run_all_unittests.cc',
+ 'usb/usb_ids_unittest.cc',
],
'conditions': [
['chromeos==1', {
diff --git a/device/usb/OWNERS b/device/usb/OWNERS
new file mode 100644
index 0000000..2ffd61a
--- /dev/null
+++ b/device/usb/OWNERS
@@ -0,0 +1,2 @@
+gdk@chromium.org
+bryeung@chromium.org
diff --git a/device/usb/usb_ids.cc b/device/usb/usb_ids.cc
new file mode 100644
index 0000000..fbb5b7e
--- /dev/null
+++ b/device/usb/usb_ids.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2012 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/usb/usb_ids.h"
+
+#include <stdlib.h>
+
+#include "base/basictypes.h"
+
+namespace device {
+
+namespace {
+
+static int CompareVendors(const void* a, const void* b) {
+ const UsbVendor* vendor_a = static_cast<const UsbVendor*>(a);
+ const UsbVendor* vendor_b = static_cast<const UsbVendor*>(b);
+ return vendor_a->id - vendor_b->id;
+}
+
+static int CompareProducts(const void* a, const void* b) {
+ const UsbProduct* product_a = static_cast<const UsbProduct*>(a);
+ const UsbProduct* product_b = static_cast<const UsbProduct*>(b);
+ return product_a->id - product_b->id;
+}
+
+} // namespace
+
+const UsbVendor* UsbIds::FindVendor(uint16_t vendor_id) {
+ const UsbVendor key = {vendor_id, NULL, 0, NULL};
+ void* result = bsearch(&key, vendors_, vendor_size_, sizeof(vendors_[0]),
+ &CompareVendors);
+ if (!result)
+ return NULL;
+ return static_cast<const UsbVendor*>(result);
+}
+
+const char* UsbIds::GetVendorName(uint16_t vendor_id) {
+ const UsbVendor* vendor = FindVendor(vendor_id);
+ if (!vendor)
+ return NULL;
+ return vendor->name;
+}
+
+const char* UsbIds::GetProductName(uint16_t vendor_id, uint16_t product_id) {
+ const UsbVendor* vendor = FindVendor(vendor_id);
+ if (!vendor)
+ return NULL;
+
+ const UsbProduct key = {product_id, NULL};
+ void* result = bsearch(&key, vendor->products, vendor->product_size,
+ sizeof(vendor->products[0]), &CompareProducts);
+ if (!result)
+ return NULL;
+ return static_cast<const UsbProduct*>(result)->name;
+}
+
+} // namespace device
diff --git a/device/usb/usb_ids.h b/device/usb/usb_ids.h
new file mode 100644
index 0000000..2f6b950
--- /dev/null
+++ b/device/usb/usb_ids.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2012 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_USB_USB_IDS_H_
+#define DEVICE_USB_USB_IDS_H_
+
+#include <stdint.h>
+
+#include "base/basictypes.h"
+
+namespace device {
+
+struct UsbProduct {
+ const uint16_t id;
+ const char* name;
+};
+
+struct UsbVendor {
+ const uint16_t id;
+ const char* name;
+ const size_t product_size;
+ const UsbProduct* products;
+};
+
+// UsbIds provides a static mapping from a vendor ID to a name, as well as a
+// mapping from a vendor/product ID pair to a product name.
+class UsbIds {
+ public:
+ // Gets the name of the vendor who owns |vendor_id|. Returns NULL if the
+ // specified |vendor_id| does not exist.
+ static const char* GetVendorName(uint16_t vendor_id);
+
+ // Gets the name of a product belonging to a specific vendor. If either
+ // |vendor_id| refers to a vendor that does not exist, or |vendor_id| is valid
+ // but |product_id| refers to a product that does not exist, this method
+ // returns NULL.
+ static const char* GetProductName(uint16_t vendor_id, uint16_t product_id);
+
+ private:
+ UsbIds();
+ ~UsbIds();
+
+ // Finds the static UsbVendor associated with |vendor_id|. Returns NULL if no
+ // such vendor exists.
+ static const UsbVendor* FindVendor(uint16_t vendor_id);
+
+ // These fields are defined in a generated file. See device/device.gyp for
+ // more information on how they are generated.
+ static const size_t vendor_size_;
+ static const UsbVendor vendors_[];
+
+ DISALLOW_COPY_AND_ASSIGN(UsbIds);
+};
+
+} // namespace device
+
+#endif // DEVICE_USB_USB_IDS_H_
diff --git a/device/usb/usb_ids_unittest.cc b/device/usb/usb_ids_unittest.cc
new file mode 100644
index 0000000..decce1e
--- /dev/null
+++ b/device/usb/usb_ids_unittest.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 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 <string>
+
+#include "device/usb/usb_ids.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+static const uint16_t kGoogleVendorId = 0x18d1;
+static const uint16_t kNexusSProductId = 0x4e21;
+
+} // namespace
+
+namespace device {
+
+TEST(UsbIdsTest, GetVendorName) {
+ EXPECT_EQ(NULL, UsbIds::GetVendorName(0));
+ EXPECT_EQ(std::string("Google Inc."), UsbIds::GetVendorName(kGoogleVendorId));
+}
+
+TEST(UsbIdsTest, GetProductName) {
+ EXPECT_EQ(NULL, UsbIds::GetProductName(0, 0));
+ EXPECT_EQ(NULL, UsbIds::GetProductName(kGoogleVendorId, 0));
+ EXPECT_EQ(std::string("Nexus S"), UsbIds::GetProductName(kGoogleVendorId,
+ kNexusSProductId));
+}
+
+} // namespace device
diff --git a/tools/usb_ids/usb_ids.py b/tools/usb_ids/usb_ids.py
new file mode 100644
index 0000000..e07bd4c
--- /dev/null
+++ b/tools/usb_ids/usb_ids.py
@@ -0,0 +1,110 @@
+# Copyright (c) 2012 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.
+
+import itertools
+import optparse
+import re
+
+VENDOR_PATTERN = re.compile("^(?P<id>[0-9a-fA-F]{4})\s+(?P<name>.+)$")
+PRODUCT_PATTERN = re.compile("^\t(?P<id>[0-9a-fA-F]{4})\s+(?P<name>.+)$")
+
+def EscapeName(name):
+ name = name.replace("\\", "\\\\")
+ name = name.replace("\"", "\\\"")
+ name = name.replace("?", "\?")
+ return name
+
+def ParseTable(input_path):
+ input_file = open(input_path, "r")
+ input = input_file.read().split("\n")
+ input_file.close()
+
+ table = {}
+ vendor = None
+
+ for line in input:
+ vendor_match = VENDOR_PATTERN.match(line)
+ if vendor_match:
+ if vendor:
+ table[vendor["id"]] = vendor
+ vendor = {}
+ vendor["id"] = int(vendor_match.group("id"), 16)
+ vendor["name"] = vendor_match.group("name")
+ vendor["products"] = []
+ continue
+
+ product_match = PRODUCT_PATTERN.match(line)
+ if product_match:
+ if not vendor:
+ raise Exception("Product seems to appear before vendor.")
+ product = {}
+ product["id"] = int(product_match.group("id"), 16)
+ product["name"] = product_match.group("name")
+ vendor["products"].append(product)
+
+ return table
+
+def GenerateDeviceDefinitions(table):
+ output = ""
+
+ for vendor_id in sorted(table.keys()):
+ vendor = table[vendor_id]
+ if len(vendor["products"]) == 0:
+ continue
+
+ output += "static const UsbProduct vendor_%.4x_products[] = {\n" % \
+ vendor["id"]
+ for product in vendor["products"]:
+ output += " {0x%.4x, \"%s\"},\n" % (product["id"],
+ EscapeName(product["name"]))
+ output += "};\n"
+
+ return output
+
+def GenerateVendorDefinitions(table):
+ output = "const size_t UsbIds::vendor_size_ = %d;\n" % len(table.keys())
+ output += "const UsbVendor UsbIds::vendors_[] = {\n"
+
+ for vendor_id in sorted(table.keys()):
+ vendor = table[vendor_id]
+
+ product_table = "NULL"
+ if len(vendor["products"]) != 0:
+ product_table = "vendor_%.4x_products" % (vendor["id"])
+ output += " {0x%.4x, \"%s\", %d, %s},\n" % (vendor["id"],
+ EscapeName(vendor["name"]), len(vendor["products"]), product_table)
+
+ output += "};\n"
+ return output
+
+if __name__ == "__main__":
+ parser = optparse.OptionParser(
+ description="Generates a C++ USB ID lookup table.")
+ parser.add_option("-i", "--input", help="Path to usb.ids")
+ parser.add_option("-o", "--output", help="Output file path")
+
+ (opts, args) = parser.parse_args()
+ table = ParseTable(opts.input)
+
+ output = """// Generated from %s
+#ifndef GENERATED_USB_IDS_H_
+#define GENERATED_USB_IDS_H_
+
+#include "device/usb/usb_ids.h"
+
+namespace device {
+
+""" % (opts.input)
+ output += GenerateDeviceDefinitions(table)
+ output += GenerateVendorDefinitions(table)
+ output += """
+
+} // namespace device
+
+#endif // GENERATED_USB_IDS_H_
+"""
+
+ output_file = open(opts.output, "w+")
+ output_file.write(output)
+ output_file.close()