Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(406)

Side by Side Diff: device/hid/hid_service_mac.cc

Issue 2780393006: Open IOHIDDevices on the FILE thread (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/hid/hid_service_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/hid/hid_service_mac.h" 5 #include "device/hid/hid_service_mac.h"
6 6
7 #include <CoreFoundation/CoreFoundation.h> 7 #include <CoreFoundation/CoreFoundation.h>
8 #include <IOKit/hid/IOHIDDevice.h>
9 #include <stdint.h> 8 #include <stdint.h>
10 9
11 #include <set> 10 #include <set>
12 #include <string> 11 #include <string>
13 #include <vector> 12 #include <vector>
14 13
15 #include "base/bind.h" 14 #include "base/bind.h"
16 #include "base/location.h" 15 #include "base/location.h"
17 #include "base/logging.h" 16 #include "base/logging.h"
18 #include "base/mac/foundation_util.h" 17 #include "base/mac/foundation_util.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 base::STLClearObject(result); 76 base::STLClearObject(result);
78 const uint8_t* bytes = CFDataGetBytePtr(ref); 77 const uint8_t* bytes = CFDataGetBytePtr(ref);
79 result->insert(result->begin(), bytes, bytes + CFDataGetLength(ref)); 78 result->insert(result->begin(), bytes, bytes + CFDataGetLength(ref));
80 return true; 79 return true;
81 } 80 }
82 81
83 } // namespace 82 } // namespace
84 83
85 HidServiceMac::HidServiceMac( 84 HidServiceMac::HidServiceMac(
86 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) 85 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner)
87 : file_task_runner_(file_task_runner) { 86 : file_task_runner_(file_task_runner), weak_factory_(this) {
88 task_runner_ = base::ThreadTaskRunnerHandle::Get(); 87 task_runner_ = base::ThreadTaskRunnerHandle::Get();
89 DCHECK(task_runner_.get()); 88 DCHECK(task_runner_.get());
90 89
91 notify_port_.reset(IONotificationPortCreate(kIOMasterPortDefault)); 90 notify_port_.reset(IONotificationPortCreate(kIOMasterPortDefault));
92 CFRunLoopAddSource(CFRunLoopGetMain(), 91 CFRunLoopAddSource(CFRunLoopGetMain(),
93 IONotificationPortGetRunLoopSource(notify_port_.get()), 92 IONotificationPortGetRunLoopSource(notify_port_.get()),
94 kCFRunLoopDefaultMode); 93 kCFRunLoopDefaultMode);
95 94
96 IOReturn result = IOServiceAddMatchingNotification( 95 IOReturn result = IOServiceAddMatchingNotification(
97 notify_port_.get(), kIOFirstMatchNotification, 96 notify_port_.get(), kIOFirstMatchNotification,
(...skipping 27 matching lines...) Expand all
125 124
126 void HidServiceMac::Connect(const HidDeviceId& device_id, 125 void HidServiceMac::Connect(const HidDeviceId& device_id,
127 const ConnectCallback& callback) { 126 const ConnectCallback& callback) {
128 DCHECK(thread_checker_.CalledOnValidThread()); 127 DCHECK(thread_checker_.CalledOnValidThread());
129 128
130 const auto& map_entry = devices().find(device_id); 129 const auto& map_entry = devices().find(device_id);
131 if (map_entry == devices().end()) { 130 if (map_entry == devices().end()) {
132 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 131 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
133 return; 132 return;
134 } 133 }
135 scoped_refptr<HidDeviceInfo> device_info = map_entry->second;
136
137 base::ScopedCFTypeRef<CFDictionaryRef> matching_dict(
138 IORegistryEntryIDMatching(device_id));
139 if (!matching_dict.get()) {
140 HID_LOG(EVENT) << "Failed to create matching dictionary for ID: "
141 << device_id;
142 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr));
143 return;
144 }
145 134
135 file_task_runner_->PostTask(
136 FROM_HERE,
137 base::Bind(&HidServiceMac::OpenOnBlockingThread, map_entry->second,
138 task_runner_, weak_factory_.GetWeakPtr(), callback));
139 }
140
141 // static
142 void HidServiceMac::OpenOnBlockingThread(
143 scoped_refptr<HidDeviceInfo> device_info,
144 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
145 base::WeakPtr<HidServiceMac> hid_service,
146 const ConnectCallback& callback) {
147 base::ScopedCFTypeRef<CFDictionaryRef> matching_dict(
148 IORegistryEntryIDMatching(device_info->device_id()));
149 if (!matching_dict.get()) {
150 HID_LOG(EVENT) << "Failed to create matching dictionary for ID: "
151 << device_info->device_id();
152 task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr));
153 return;
154 }
155
146 // IOServiceGetMatchingService consumes a reference to the matching dictionary 156 // IOServiceGetMatchingService consumes a reference to the matching dictionary
147 // passed to it. 157 // passed to it.
148 base::mac::ScopedIOObject<io_service_t> service(IOServiceGetMatchingService( 158 base::mac::ScopedIOObject<io_service_t> service(IOServiceGetMatchingService(
149 kIOMasterPortDefault, matching_dict.release())); 159 kIOMasterPortDefault, matching_dict.release()));
150 if (!service.get()) { 160 if (!service.get()) {
151 HID_LOG(EVENT) << "IOService not found for ID: " << device_id; 161 HID_LOG(EVENT) << "IOService not found for ID: "
152 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 162 << device_info->device_id();
163 task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr));
153 return; 164 return;
154 } 165 }
155 166
156 base::ScopedCFTypeRef<IOHIDDeviceRef> hid_device( 167 base::ScopedCFTypeRef<IOHIDDeviceRef> hid_device(
157 IOHIDDeviceCreate(kCFAllocatorDefault, service)); 168 IOHIDDeviceCreate(kCFAllocatorDefault, service));
158 if (!hid_device) { 169 if (!hid_device) {
159 HID_LOG(EVENT) << "Unable to create IOHIDDevice object."; 170 HID_LOG(EVENT) << "Unable to create IOHIDDevice object.";
160 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 171 task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr));
161 return; 172 return;
162 } 173 }
163 174
164 IOReturn result = IOHIDDeviceOpen(hid_device, kIOHIDOptionsTypeNone); 175 IOReturn result = IOHIDDeviceOpen(hid_device, kIOHIDOptionsTypeNone);
165 if (result != kIOReturnSuccess) { 176 if (result != kIOReturnSuccess) {
166 HID_LOG(EVENT) << "Failed to open device: " << HexErrorCode(result); 177 HID_LOG(EVENT) << "Failed to open device: " << HexErrorCode(result);
167 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); 178 task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr));
168 return; 179 return;
169 } 180 }
170 181
171 task_runner_->PostTask( 182 task_runner->PostTask(
172 FROM_HERE, base::Bind(callback, make_scoped_refptr(new HidConnectionMac( 183 FROM_HERE, base::Bind(&HidServiceMac::DeviceOpened, hid_service,
173 hid_device.release(), device_info, 184 device_info, base::Passed(&hid_device), callback));
174 file_task_runner_)))); 185 }
186
187 void HidServiceMac::DeviceOpened(
188 scoped_refptr<HidDeviceInfo> device_info,
189 base::ScopedCFTypeRef<IOHIDDeviceRef> hid_device,
190 const ConnectCallback& callback) {
191 callback.Run(make_scoped_refptr(new HidConnectionMac(
192 std::move(hid_device), std::move(device_info), file_task_runner_)));
175 } 193 }
176 194
177 // static 195 // static
178 void HidServiceMac::FirstMatchCallback(void* context, io_iterator_t iterator) { 196 void HidServiceMac::FirstMatchCallback(void* context, io_iterator_t iterator) {
179 DCHECK_EQ(CFRunLoopGetMain(), CFRunLoopGetCurrent()); 197 DCHECK_EQ(CFRunLoopGetMain(), CFRunLoopGetCurrent());
180 HidServiceMac* service = static_cast<HidServiceMac*>(context); 198 HidServiceMac* service = static_cast<HidServiceMac*>(context);
181 DCHECK_EQ(service->devices_added_iterator_, iterator); 199 DCHECK_EQ(service->devices_added_iterator_, iterator);
182 service->AddDevices(); 200 service->AddDevices();
183 } 201 }
184 202
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 return new HidDeviceInfo( 270 return new HidDeviceInfo(
253 entry_id, GetHidIntProperty(hid_device, CFSTR(kIOHIDVendorIDKey)), 271 entry_id, GetHidIntProperty(hid_device, CFSTR(kIOHIDVendorIDKey)),
254 GetHidIntProperty(hid_device, CFSTR(kIOHIDProductIDKey)), 272 GetHidIntProperty(hid_device, CFSTR(kIOHIDProductIDKey)),
255 GetHidStringProperty(hid_device, CFSTR(kIOHIDProductKey)), 273 GetHidStringProperty(hid_device, CFSTR(kIOHIDProductKey)),
256 GetHidStringProperty(hid_device, CFSTR(kIOHIDSerialNumberKey)), 274 GetHidStringProperty(hid_device, CFSTR(kIOHIDSerialNumberKey)),
257 kHIDBusTypeUSB, // TODO(reillyg): Detect Bluetooth. crbug.com/443335 275 kHIDBusTypeUSB, // TODO(reillyg): Detect Bluetooth. crbug.com/443335
258 report_descriptor); 276 report_descriptor);
259 } 277 }
260 278
261 } // namespace device 279 } // namespace device
OLDNEW
« no previous file with comments | « device/hid/hid_service_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698