Chromium Code Reviews| Index: device/hid/hid_service_mac.cc |
| diff --git a/device/hid/hid_service_mac.cc b/device/hid/hid_service_mac.cc |
| index ed85ec2d5cc922c51397f5e09a6dba3168ebdd5a..67ad164d5e96079bab8cbe0d6bb14ffdcaba60e7 100644 |
| --- a/device/hid/hid_service_mac.cc |
| +++ b/device/hid/hid_service_mac.cc |
| @@ -7,17 +7,19 @@ |
| #include <CoreFoundation/CoreFoundation.h> |
| #include <IOKit/hid/IOHIDManager.h> |
| +#include <set> |
| #include <string> |
| #include <vector> |
| #include "base/bind.h" |
| #include "base/logging.h" |
| +#include "base/mac/foundation_util.h" |
| #include "base/message_loop/message_loop_proxy.h" |
| #include "base/stl_util.h" |
| #include "base/strings/string_number_conversions.h" |
| +#include "base/strings/sys_string_conversions.h" |
| #include "base/threading/thread_restrictions.h" |
| #include "device/hid/hid_connection_mac.h" |
| -#include "device/hid/hid_utils_mac.h" |
| namespace device { |
| @@ -48,6 +50,89 @@ void EnumerateHidDevices(IOHIDManagerRef hid_manager, |
| CFSetApplyFunction(devices, HidEnumerationBackInserter, device_list); |
| } |
| +bool TryGetHidIntProperty(IOHIDDeviceRef device, |
| + CFStringRef key, |
| + int32_t* result) { |
| + CFNumberRef ref = |
| + base::mac::CFCast<CFNumberRef>(IOHIDDeviceGetProperty(device, key)); |
| + return ref && CFNumberGetValue(ref, kCFNumberSInt32Type, result); |
| +} |
| + |
| +int32_t GetHidIntProperty(IOHIDDeviceRef device, CFStringRef key) { |
| + int32_t value; |
| + if (TryGetHidIntProperty(device, key, &value)) |
| + return value; |
| + return 0; |
| +} |
| + |
| +bool TryGetHidStringProperty(IOHIDDeviceRef device, |
| + CFStringRef key, |
| + std::string* result) { |
| + CFStringRef ref = |
| + base::mac::CFCast<CFStringRef>(IOHIDDeviceGetProperty(device, key)); |
| + if (!ref) { |
| + return false; |
| + } |
| + *result = base::SysCFStringRefToUTF8(ref); |
| + return true; |
| +} |
| + |
| +std::string GetHidStringProperty(IOHIDDeviceRef device, CFStringRef key) { |
| + std::string value; |
| + TryGetHidStringProperty(device, key, &value); |
| + return value; |
| +} |
| + |
| +void GetReportIds(IOHIDElementRef element, std::set<int>& reportIDs) { |
| + CFArrayRef children = IOHIDElementGetChildren(element); |
| + if (!children) |
| + return; |
| + CFIndex childrenCount = CFArrayGetCount(children); |
| + for (CFIndex j = 0; j < childrenCount; ++j) { |
| + IOHIDElementRef child = static_cast<IOHIDElementRef>( |
| + const_cast<void*>(CFArrayGetValueAtIndex(children, j))); |
| + uint32_t reportID = IOHIDElementGetReportID(child); |
| + if (reportID) { |
| + reportIDs.insert(reportID); |
| + } |
| + GetReportIds(child, reportIDs); |
| + } |
| +} |
| + |
| +void GetCollectionInfos(IOHIDDeviceRef device, |
| + 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); |
| + CFIndex collectionsCount = CFArrayGetCount(collections); |
| + for (CFIndex i = 0; i < collectionsCount; i++) { |
| + IOHIDElementRef collection = static_cast<IOHIDElementRef>( |
|
Ken Rockot(use gerrit already)
2014/06/27 14:50:23
Is there any reason you can't cast to a const IOHI
jracle (use Gerrit)
2014/06/27 20:07:07
oh I did an horror.. I should use only const_cast
|
| + 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)); |
| + uint16_t usage = IOHIDElementGetUsage(collection); |
| + collection_info.usage = HidUsageAndPage(usage, page); |
| + // Explore children recursively and retrieve their report IDs |
| + GetReportIds(collection, collection_info.report_ids); |
| + top_level_collections->push_back(collection_info); |
| + } |
| + } |
| +} |
| + |
| } // namespace |
| HidServiceMac::HidServiceMac() { |
| @@ -136,41 +221,23 @@ void HidServiceMac::PlatformAddDevice(IOHIDDeviceRef hid_device) { |
| // Note that our ownership of hid_device is implied if calling this method. |
| // It is balanced in PlatformRemoveDevice. |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - |
| HidDeviceInfo device_info; |
| device_info.device_id = hid_device; |
| device_info.vendor_id = |
| GetHidIntProperty(hid_device, CFSTR(kIOHIDVendorIDKey)); |
| device_info.product_id = |
| GetHidIntProperty(hid_device, CFSTR(kIOHIDProductIDKey)); |
| - device_info.input_report_size = |
| - GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxInputReportSizeKey)); |
| - device_info.output_report_size = |
| - GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxOutputReportSizeKey)); |
| - device_info.feature_report_size = |
| - GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxFeatureReportSizeKey)); |
| - CFTypeRef deviceUsagePairsRaw = |
| - IOHIDDeviceGetProperty(hid_device, CFSTR(kIOHIDDeviceUsagePairsKey)); |
| - CFArrayRef deviceUsagePairs = |
| - base::mac::CFCast<CFArrayRef>(deviceUsagePairsRaw); |
| - CFIndex deviceUsagePairsCount = CFArrayGetCount(deviceUsagePairs); |
| - for (CFIndex i = 0; i < deviceUsagePairsCount; i++) { |
| - CFDictionaryRef deviceUsagePair = base::mac::CFCast<CFDictionaryRef>( |
| - CFArrayGetValueAtIndex(deviceUsagePairs, i)); |
| - CFNumberRef usage_raw = base::mac::CFCast<CFNumberRef>( |
| - CFDictionaryGetValue(deviceUsagePair, CFSTR(kIOHIDDeviceUsageKey))); |
| - uint16_t usage; |
| - CFNumberGetValue(usage_raw, kCFNumberSInt32Type, &usage); |
| - CFNumberRef page_raw = base::mac::CFCast<CFNumberRef>( |
| - CFDictionaryGetValue(deviceUsagePair, CFSTR(kIOHIDDeviceUsagePageKey))); |
| - HidUsageAndPage::Page page; |
| - CFNumberGetValue(page_raw, kCFNumberSInt32Type, &page); |
| - device_info.usages.push_back(HidUsageAndPage(usage, page)); |
| - } |
| device_info.product_name = |
| GetHidStringProperty(hid_device, CFSTR(kIOHIDProductKey)); |
| device_info.serial_number = |
| GetHidStringProperty(hid_device, CFSTR(kIOHIDSerialNumberKey)); |
| + GetCollectionInfos(hid_device, &device_info.collections); |
| + device_info.max_input_report_size = |
| + GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxInputReportSizeKey)); |
| + device_info.max_output_report_size = |
| + GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxOutputReportSizeKey)); |
| + device_info.max_feature_report_size = |
| + GetHidIntProperty(hid_device, CFSTR(kIOHIDMaxFeatureReportSizeKey)); |
| AddDevice(device_info); |
| } |