OLD | NEW |
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_win.h" | 5 #include "device/hid/hid_service_win.h" |
6 | 6 |
7 #define INITGUID | 7 #define INITGUID |
8 | 8 |
9 #include <dbt.h> | 9 #include <dbt.h> |
10 #include <setupapi.h> | 10 #include <setupapi.h> |
(...skipping 29 matching lines...) Expand all Loading... |
40 } | 40 } |
41 | 41 |
42 void HidServiceWin::Connect(const HidDeviceId& device_id, | 42 void HidServiceWin::Connect(const HidDeviceId& device_id, |
43 const ConnectCallback& callback) { | 43 const ConnectCallback& callback) { |
44 DCHECK(thread_checker_.CalledOnValidThread()); | 44 DCHECK(thread_checker_.CalledOnValidThread()); |
45 const auto& map_entry = devices().find(device_id); | 45 const auto& map_entry = devices().find(device_id); |
46 if (map_entry == devices().end()) { | 46 if (map_entry == devices().end()) { |
47 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 47 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); |
48 return; | 48 return; |
49 } | 49 } |
50 const HidDeviceInfo& device_info = map_entry->second; | 50 scoped_refptr<HidDeviceInfo> device_info = map_entry->second; |
51 | 51 |
52 base::win::ScopedHandle file(OpenDevice(device_info.device_id)); | 52 base::win::ScopedHandle file(OpenDevice(device_info->device_id())); |
53 if (!file.IsValid()) { | 53 if (!file.IsValid()) { |
54 PLOG(ERROR) << "Failed to open device"; | 54 PLOG(ERROR) << "Failed to open device"; |
55 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 55 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); |
56 return; | 56 return; |
57 } | 57 } |
58 | 58 |
59 task_runner_->PostTask( | 59 task_runner_->PostTask( |
60 FROM_HERE, | 60 FROM_HERE, |
61 base::Bind(callback, new HidConnectionWin(device_info, file.Pass()))); | 61 base::Bind(callback, new HidConnectionWin(device_info, file.Pass()))); |
62 } | 62 } |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 int report_id = value_caps[i].ReportID; | 149 int report_id = value_caps[i].ReportID; |
150 if (report_id != 0) { | 150 if (report_id != 0) { |
151 collection_info->report_ids.insert(report_id); | 151 collection_info->report_ids.insert(report_id); |
152 } | 152 } |
153 } | 153 } |
154 } | 154 } |
155 } | 155 } |
156 } | 156 } |
157 | 157 |
158 void HidServiceWin::OnDeviceAdded(const std::string& device_path) { | 158 void HidServiceWin::OnDeviceAdded(const std::string& device_path) { |
159 HidDeviceInfo device_info; | |
160 device_info.device_id = device_path; | |
161 | |
162 // Try to open the device. | 159 // Try to open the device. |
163 base::win::ScopedHandle device_handle(OpenDevice(device_path)); | 160 base::win::ScopedHandle device_handle(OpenDevice(device_path)); |
164 if (!device_handle.IsValid()) { | 161 if (!device_handle.IsValid()) { |
165 return; | 162 return; |
166 } | 163 } |
167 | 164 |
168 // Get VID/PID pair. | 165 // Get VID/PID pair. |
169 HIDD_ATTRIBUTES attrib = {0}; | 166 HIDD_ATTRIBUTES attrib = {0}; |
170 attrib.Size = sizeof(HIDD_ATTRIBUTES); | 167 attrib.Size = sizeof(HIDD_ATTRIBUTES); |
171 if (!HidD_GetAttributes(device_handle.Get(), &attrib)) { | 168 if (!HidD_GetAttributes(device_handle.Get(), &attrib)) { |
172 return; | 169 return; |
173 } | 170 } |
174 | 171 |
175 device_info.vendor_id = attrib.VendorID; | 172 scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo()); |
176 device_info.product_id = attrib.ProductID; | 173 device_info->device_id_ = device_path; |
| 174 device_info->vendor_id_ = attrib.VendorID; |
| 175 device_info->product_id_ = attrib.ProductID; |
177 | 176 |
178 // Get usage and usage page (optional). | 177 // Get usage and usage page (optional). |
179 PHIDP_PREPARSED_DATA preparsed_data; | 178 PHIDP_PREPARSED_DATA preparsed_data; |
180 if (HidD_GetPreparsedData(device_handle.Get(), &preparsed_data) && | 179 if (HidD_GetPreparsedData(device_handle.Get(), &preparsed_data) && |
181 preparsed_data) { | 180 preparsed_data) { |
182 HIDP_CAPS capabilities = {0}; | 181 HIDP_CAPS capabilities = {0}; |
183 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) { | 182 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) { |
184 device_info.max_input_report_size = capabilities.InputReportByteLength; | 183 device_info->max_input_report_size_ = capabilities.InputReportByteLength; |
185 device_info.max_output_report_size = capabilities.OutputReportByteLength; | 184 device_info->max_output_report_size_ = |
186 device_info.max_feature_report_size = | 185 capabilities.OutputReportByteLength; |
| 186 device_info->max_feature_report_size_ = |
187 capabilities.FeatureReportByteLength; | 187 capabilities.FeatureReportByteLength; |
188 HidCollectionInfo collection_info; | 188 HidCollectionInfo collection_info; |
189 collection_info.usage = HidUsageAndPage( | 189 collection_info.usage = HidUsageAndPage( |
190 capabilities.Usage, | 190 capabilities.Usage, |
191 static_cast<HidUsageAndPage::Page>(capabilities.UsagePage)); | 191 static_cast<HidUsageAndPage::Page>(capabilities.UsagePage)); |
192 CollectInfoFromButtonCaps(preparsed_data, | 192 CollectInfoFromButtonCaps(preparsed_data, |
193 HidP_Input, | 193 HidP_Input, |
194 capabilities.NumberInputButtonCaps, | 194 capabilities.NumberInputButtonCaps, |
195 &collection_info); | 195 &collection_info); |
196 CollectInfoFromButtonCaps(preparsed_data, | 196 CollectInfoFromButtonCaps(preparsed_data, |
(...skipping 10 matching lines...) Expand all Loading... |
207 &collection_info); | 207 &collection_info); |
208 CollectInfoFromValueCaps(preparsed_data, | 208 CollectInfoFromValueCaps(preparsed_data, |
209 HidP_Output, | 209 HidP_Output, |
210 capabilities.NumberOutputValueCaps, | 210 capabilities.NumberOutputValueCaps, |
211 &collection_info); | 211 &collection_info); |
212 CollectInfoFromValueCaps(preparsed_data, | 212 CollectInfoFromValueCaps(preparsed_data, |
213 HidP_Feature, | 213 HidP_Feature, |
214 capabilities.NumberFeatureValueCaps, | 214 capabilities.NumberFeatureValueCaps, |
215 &collection_info); | 215 &collection_info); |
216 if (!collection_info.report_ids.empty()) { | 216 if (!collection_info.report_ids.empty()) { |
217 device_info.has_report_id = true; | 217 device_info->has_report_id_ = true; |
218 } | 218 } |
219 device_info.collections.push_back(collection_info); | 219 device_info->collections_.push_back(collection_info); |
220 } | 220 } |
221 // Whether or not the device includes report IDs in its reports the size | 221 // Whether or not the device includes report IDs in its reports the size |
222 // of the report ID is included in the value provided by Windows. This | 222 // of the report ID is included in the value provided by Windows. This |
223 // appears contrary to the MSDN documentation. | 223 // appears contrary to the MSDN documentation. |
224 if (device_info.max_input_report_size > 0) { | 224 if (device_info->max_input_report_size() > 0) { |
225 device_info.max_input_report_size--; | 225 device_info->max_input_report_size_--; |
226 } | 226 } |
227 if (device_info.max_output_report_size > 0) { | 227 if (device_info->max_output_report_size() > 0) { |
228 device_info.max_output_report_size--; | 228 device_info->max_output_report_size_--; |
229 } | 229 } |
230 if (device_info.max_feature_report_size > 0) { | 230 if (device_info->max_feature_report_size() > 0) { |
231 device_info.max_feature_report_size--; | 231 device_info->max_feature_report_size_--; |
232 } | 232 } |
233 HidD_FreePreparsedData(preparsed_data); | 233 HidD_FreePreparsedData(preparsed_data); |
234 } | 234 } |
235 | 235 |
236 AddDevice(device_info); | 236 AddDevice(device_info); |
237 } | 237 } |
238 | 238 |
239 void HidServiceWin::OnDeviceRemoved(const std::string& device_path) { | 239 void HidServiceWin::OnDeviceRemoved(const std::string& device_path) { |
240 RemoveDevice(device_path); | 240 RemoveDevice(device_path); |
241 } | 241 } |
242 | 242 |
243 base::win::ScopedHandle HidServiceWin::OpenDevice( | 243 base::win::ScopedHandle HidServiceWin::OpenDevice( |
244 const std::string& device_path) { | 244 const std::string& device_path) { |
245 base::win::ScopedHandle file( | 245 base::win::ScopedHandle file( |
246 CreateFileA(device_path.c_str(), GENERIC_WRITE | GENERIC_READ, | 246 CreateFileA(device_path.c_str(), GENERIC_WRITE | GENERIC_READ, |
247 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, | 247 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, |
248 FILE_FLAG_OVERLAPPED, NULL)); | 248 FILE_FLAG_OVERLAPPED, NULL)); |
249 if (!file.IsValid() && | 249 if (!file.IsValid() && |
250 GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) { | 250 GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) { |
251 file.Set(CreateFileA(device_path.c_str(), GENERIC_READ, FILE_SHARE_READ, | 251 file.Set(CreateFileA(device_path.c_str(), GENERIC_READ, FILE_SHARE_READ, |
252 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)); | 252 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)); |
253 } | 253 } |
254 return file.Pass(); | 254 return file.Pass(); |
255 } | 255 } |
256 | 256 |
257 } // namespace device | 257 } // namespace device |
OLD | NEW |