summaryrefslogtreecommitdiffstats
path: root/device/hid/hid_service_mac.cc
diff options
context:
space:
mode:
authorreillyg <reillyg@chromium.org>2015-01-12 19:07:11 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-13 03:08:07 +0000
commit37cde99564e8a0789b5904680fa60aa046c6efcc (patch)
tree2a764f83cacfd6328117f0c502a1ec44ec2d851c /device/hid/hid_service_mac.cc
parent8dec34f8f3504352e4eef95b2aaa36c561aea930 (diff)
downloadchromium_src-37cde99564e8a0789b5904680fa60aa046c6efcc.zip
chromium_src-37cde99564e8a0789b5904680fa60aa046c6efcc.tar.gz
chromium_src-37cde99564e8a0789b5904680fa60aa046c6efcc.tar.bz2
Include raw HID report descriptor in HID device info.
This change includes the raw HID report descriptor in the HidDeviceInfo class and exposes it to apps and extensions using the chrome.hid API. For simplicity on OS X the platform APIs for collecting information from the report descriptor are no longer used and instead the parsing code from Linux is used. On Windows the raw HID report descriptor is not available because Windows exposes HID devices on a per-top-level collection basis. BUG=442818 Review URL: https://codereview.chromium.org/801833003 Cr-Commit-Position: refs/heads/master@{#311192}
Diffstat (limited to 'device/hid/hid_service_mac.cc')
-rw-r--r--device/hid/hid_service_mac.cc114
1 files changed, 20 insertions, 94 deletions
diff --git a/device/hid/hid_service_mac.cc b/device/hid/hid_service_mac.cc
index 5c3f5bd..de6861d 100644
--- a/device/hid/hid_service_mac.cc
+++ b/device/hid/hid_service_mac.cc
@@ -60,70 +60,17 @@ std::string GetHidStringProperty(IOHIDDeviceRef device, CFStringRef key) {
return value;
}
-void GetReportIds(IOHIDElementRef element, std::set<int>* reportIDs) {
- uint32_t reportID = IOHIDElementGetReportID(element);
- if (reportID) {
- reportIDs->insert(reportID);
- }
-
- CFArrayRef children = IOHIDElementGetChildren(element);
- if (!children) {
- return;
- }
-
- CFIndex childrenCount = CFArrayGetCount(children);
- for (CFIndex j = 0; j < childrenCount; ++j) {
- const IOHIDElementRef child = static_cast<IOHIDElementRef>(
- const_cast<void*>(CFArrayGetValueAtIndex(children, j)));
- GetReportIds(child, reportIDs);
- }
-}
-
-bool GetCollectionInfos(IOHIDDeviceRef device,
- bool* has_report_id,
- std::vector<HidCollectionInfo>* top_level_collections) {
- STLClearObject(top_level_collections);
- CFMutableDictionaryRef collections_filter =
- CFDictionaryCreateMutable(kCFAllocatorDefault,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- const int kCollectionTypeValue = kIOHIDElementTypeCollection;
- CFNumberRef collection_type_id = CFNumberCreate(
- kCFAllocatorDefault, kCFNumberIntType, &kCollectionTypeValue);
- CFDictionarySetValue(
- collections_filter, CFSTR(kIOHIDElementTypeKey), collection_type_id);
- CFRelease(collection_type_id);
- CFArrayRef collections = IOHIDDeviceCopyMatchingElements(
- device, collections_filter, kIOHIDOptionsTypeNone);
- if (!collections) {
+bool TryGetHidDataProperty(IOHIDDeviceRef device,
+ CFStringRef key,
+ std::vector<uint8>* result) {
+ CFDataRef ref =
+ base::mac::CFCast<CFDataRef>(IOHIDDeviceGetProperty(device, key));
+ if (!ref) {
return false;
}
-
- CFIndex collectionsCount = CFArrayGetCount(collections);
- *has_report_id = false;
- for (CFIndex i = 0; i < collectionsCount; i++) {
- const IOHIDElementRef collection = static_cast<IOHIDElementRef>(
- const_cast<void*>(CFArrayGetValueAtIndex(collections, i)));
- // Top-Level Collection has no parent
- if (IOHIDElementGetParent(collection) == 0) {
- HidCollectionInfo collection_info;
- HidUsageAndPage::Page page = static_cast<HidUsageAndPage::Page>(
- IOHIDElementGetUsagePage(collection));
- uint32_t usage = IOHIDElementGetUsage(collection);
- if (usage > std::numeric_limits<uint16_t>::max())
- continue;
- collection_info.usage =
- HidUsageAndPage(static_cast<uint16_t>(usage), page);
- // Explore children recursively and retrieve their report IDs
- GetReportIds(collection, &collection_info.report_ids);
- if (collection_info.report_ids.size() > 0) {
- *has_report_id = true;
- }
- top_level_collections->push_back(collection_info);
- }
- }
-
+ STLClearObject(result);
+ const uint8* bytes = CFDataGetBytePtr(ref);
+ result->insert(result->begin(), bytes, bytes + CFDataGetLength(ref));
return true;
}
@@ -278,7 +225,6 @@ void HidServiceMac::RemoveDevices() {
// static
scoped_refptr<HidDeviceInfo> HidServiceMac::CreateDeviceInfo(
io_service_t service) {
- scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo());
io_string_t service_path;
IOReturn result =
IORegistryEntryGetPath(service, kIOServicePlane, service_path);
@@ -296,40 +242,20 @@ scoped_refptr<HidDeviceInfo> HidServiceMac::CreateDeviceInfo(
return nullptr;
}
- device_info->device_id_ = service_path;
- device_info->vendor_id_ =
- GetHidIntProperty(hid_device, CFSTR(kIOHIDVendorIDKey));
- device_info->product_id_ =
- GetHidIntProperty(hid_device, CFSTR(kIOHIDProductIDKey));
- device_info->product_name_ =
- GetHidStringProperty(hid_device, CFSTR(kIOHIDProductKey));
- device_info->serial_number_ =
- GetHidStringProperty(hid_device, CFSTR(kIOHIDSerialNumberKey));
- if (!GetCollectionInfos(hid_device, &device_info->has_report_id_,
- &device_info->collections_)) {
- VLOG(1) << "Unable to get collection info for " << service_path << ".";
+ std::vector<uint8> report_descriptor;
+ if (!TryGetHidDataProperty(hid_device, CFSTR(kIOHIDReportDescriptorKey),
+ &report_descriptor)) {
+ VLOG(1) << "Unable to get report descriptor for " << service_path << ".";
return nullptr;
}
- device_info->max_input_report_size_ =
- GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxInputReportSizeKey));
- if (device_info->has_report_id() &&
- device_info->max_input_report_size() > 0) {
- device_info->max_input_report_size_--;
- }
- device_info->max_output_report_size_ =
- GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxOutputReportSizeKey));
- if (device_info->has_report_id() &&
- device_info->max_output_report_size_ > 0) {
- device_info->max_output_report_size_--;
- }
- device_info->max_feature_report_size_ =
- GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxFeatureReportSizeKey));
- if (device_info->has_report_id() &&
- device_info->max_feature_report_size_ > 0) {
- device_info->max_feature_report_size_--;
- }
- return device_info;
+ return new HidDeviceInfo(
+ service_path, GetHidIntProperty(hid_device, CFSTR(kIOHIDVendorIDKey)),
+ GetHidIntProperty(hid_device, CFSTR(kIOHIDProductIDKey)),
+ GetHidStringProperty(hid_device, CFSTR(kIOHIDProductKey)),
+ GetHidStringProperty(hid_device, CFSTR(kIOHIDSerialNumberKey)),
+ kHIDBusTypeUSB, // TODO(reillyg): Detect Bluetooth. crbug.com/443335
+ report_descriptor);
}
} // namespace device