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/usb/usb_device_impl.h" | 5 #include "device/usb/usb_device_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 const char* value = udev_device_get_sysattr_value(device.get(), "busnum"); | 151 const char* value = udev_device_get_sysattr_value(device.get(), "busnum"); |
152 if (!value || bus_number != value) { | 152 if (!value || bus_number != value) { |
153 continue; | 153 continue; |
154 } | 154 } |
155 value = udev_device_get_sysattr_value(device.get(), "devnum"); | 155 value = udev_device_get_sysattr_value(device.get(), "devnum"); |
156 if (!value || device_address != value) { | 156 if (!value || device_address != value) { |
157 continue; | 157 continue; |
158 } | 158 } |
159 | 159 |
160 value = udev_device_get_sysattr_value(device.get(), "manufacturer"); | 160 value = udev_device_get_sysattr_value(device.get(), "manufacturer"); |
161 manufacturer_ = value ? value : ""; | 161 if (value) { |
| 162 manufacturer_ = base::UTF8ToUTF16(value); |
| 163 } |
162 value = udev_device_get_sysattr_value(device.get(), "product"); | 164 value = udev_device_get_sysattr_value(device.get(), "product"); |
163 product_ = value ? value : ""; | 165 if (value) { |
| 166 product_ = base::UTF8ToUTF16(value); |
| 167 } |
164 value = udev_device_get_sysattr_value(device.get(), "serial"); | 168 value = udev_device_get_sysattr_value(device.get(), "serial"); |
165 serial_number_ = value ? value : ""; | 169 if (value) { |
| 170 serial_number_ = base::UTF8ToUTF16(value); |
| 171 } |
166 break; | 172 break; |
167 } | 173 } |
168 } | 174 } |
| 175 #else |
| 176 strings_cached_ = false; |
169 #endif | 177 #endif |
170 } | 178 } |
171 | 179 |
172 UsbDeviceImpl::~UsbDeviceImpl() { | 180 UsbDeviceImpl::~UsbDeviceImpl() { |
173 DCHECK(thread_checker_.CalledOnValidThread()); | 181 DCHECK(thread_checker_.CalledOnValidThread()); |
174 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end(); | 182 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end(); |
175 ++it) { | 183 ++it) { |
176 (*it)->InternalClose(); | 184 (*it)->InternalClose(); |
177 } | 185 } |
178 STLClearObject(&handles_); | 186 STLClearObject(&handles_); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 | 220 |
213 #endif | 221 #endif |
214 | 222 |
215 scoped_refptr<UsbDeviceHandle> UsbDeviceImpl::Open() { | 223 scoped_refptr<UsbDeviceHandle> UsbDeviceImpl::Open() { |
216 DCHECK(thread_checker_.CalledOnValidThread()); | 224 DCHECK(thread_checker_.CalledOnValidThread()); |
217 PlatformUsbDeviceHandle handle; | 225 PlatformUsbDeviceHandle handle; |
218 const int rv = libusb_open(platform_device_, &handle); | 226 const int rv = libusb_open(platform_device_, &handle); |
219 if (LIBUSB_SUCCESS == rv) { | 227 if (LIBUSB_SUCCESS == rv) { |
220 GetConfiguration(); | 228 GetConfiguration(); |
221 if (!current_configuration_cached_) { | 229 if (!current_configuration_cached_) { |
| 230 libusb_close(handle); |
222 return NULL; | 231 return NULL; |
223 } | 232 } |
224 scoped_refptr<UsbDeviceHandleImpl> device_handle = | 233 scoped_refptr<UsbDeviceHandleImpl> device_handle = |
225 new UsbDeviceHandleImpl(context_, this, handle, current_configuration_); | 234 new UsbDeviceHandleImpl(context_, this, handle, current_configuration_); |
226 handles_.push_back(device_handle); | 235 handles_.push_back(device_handle); |
227 return device_handle; | 236 return device_handle; |
228 } else { | 237 } else { |
229 VLOG(1) << "Failed to open device: " << ConvertPlatformUsbErrorToString(rv); | 238 VLOG(1) << "Failed to open device: " << ConvertPlatformUsbErrorToString(rv); |
230 return NULL; | 239 return NULL; |
231 } | 240 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 libusb_free_config_descriptor(platform_config); | 324 libusb_free_config_descriptor(platform_config); |
316 current_configuration_cached_ = true; | 325 current_configuration_cached_ = true; |
317 } | 326 } |
318 | 327 |
319 return current_configuration_; | 328 return current_configuration_; |
320 } | 329 } |
321 | 330 |
322 bool UsbDeviceImpl::GetManufacturer(base::string16* manufacturer) { | 331 bool UsbDeviceImpl::GetManufacturer(base::string16* manufacturer) { |
323 DCHECK(thread_checker_.CalledOnValidThread()); | 332 DCHECK(thread_checker_.CalledOnValidThread()); |
324 | 333 |
325 #if defined(USE_UDEV) | 334 #if !defined(USE_UDEV) |
326 if (manufacturer_.empty()) { | 335 if (!strings_cached_) { |
327 return false; | 336 CacheStrings(); |
328 } | 337 } |
329 *manufacturer = base::UTF8ToUTF16(manufacturer_); | 338 #endif |
330 return true; | |
331 #else | |
332 // This is a non-blocking call as libusb has the descriptor in memory. | |
333 libusb_device_descriptor desc; | |
334 const int rv = libusb_get_device_descriptor(platform_device_, &desc); | |
335 if (rv != LIBUSB_SUCCESS) { | |
336 VLOG(1) << "Failed to read device descriptor: " | |
337 << ConvertPlatformUsbErrorToString(rv); | |
338 return false; | |
339 } | |
340 | 339 |
341 if (desc.iManufacturer == 0) { | 340 *manufacturer = manufacturer_; |
342 return false; | 341 return !manufacturer_.empty(); |
343 } | |
344 | |
345 scoped_refptr<UsbDeviceHandle> device_handle = Open(); | |
346 if (device_handle.get()) { | |
347 return device_handle->GetStringDescriptor(desc.iManufacturer, manufacturer); | |
348 } | |
349 return false; | |
350 #endif | |
351 } | 342 } |
352 | 343 |
353 bool UsbDeviceImpl::GetProduct(base::string16* product) { | 344 bool UsbDeviceImpl::GetProduct(base::string16* product) { |
354 DCHECK(thread_checker_.CalledOnValidThread()); | 345 DCHECK(thread_checker_.CalledOnValidThread()); |
355 | 346 |
356 #if defined(USE_UDEV) | 347 #if !defined(USE_UDEV) |
357 if (product_.empty()) { | 348 if (!strings_cached_) { |
358 return false; | 349 CacheStrings(); |
359 } | 350 } |
360 *product = base::UTF8ToUTF16(product_); | 351 #endif |
361 return true; | |
362 #else | |
363 // This is a non-blocking call as libusb has the descriptor in memory. | |
364 libusb_device_descriptor desc; | |
365 const int rv = libusb_get_device_descriptor(platform_device_, &desc); | |
366 if (rv != LIBUSB_SUCCESS) { | |
367 VLOG(1) << "Failed to read device descriptor: " | |
368 << ConvertPlatformUsbErrorToString(rv); | |
369 return false; | |
370 } | |
371 | 352 |
372 if (desc.iProduct == 0) { | 353 *product = product_; |
373 return false; | 354 return !product_.empty(); |
374 } | |
375 | |
376 scoped_refptr<UsbDeviceHandle> device_handle = Open(); | |
377 if (device_handle.get()) { | |
378 return device_handle->GetStringDescriptor(desc.iProduct, product); | |
379 } | |
380 return false; | |
381 #endif | |
382 } | 355 } |
383 | 356 |
384 bool UsbDeviceImpl::GetSerialNumber(base::string16* serial_number) { | 357 bool UsbDeviceImpl::GetSerialNumber(base::string16* serial_number) { |
385 DCHECK(thread_checker_.CalledOnValidThread()); | 358 DCHECK(thread_checker_.CalledOnValidThread()); |
386 | 359 |
387 #if defined(USE_UDEV) | 360 #if !defined(USE_UDEV) |
388 if (serial_number_.empty()) { | 361 if (!strings_cached_) { |
389 return false; | 362 CacheStrings(); |
390 } | 363 } |
391 *serial_number = base::UTF8ToUTF16(serial_number_); | 364 #endif |
392 return true; | |
393 #else | |
394 // This is a non-blocking call as libusb has the descriptor in memory. | |
395 libusb_device_descriptor desc; | |
396 const int rv = libusb_get_device_descriptor(platform_device_, &desc); | |
397 if (rv != LIBUSB_SUCCESS) { | |
398 VLOG(1) << "Failed to read device descriptor: " | |
399 << ConvertPlatformUsbErrorToString(rv); | |
400 return false; | |
401 } | |
402 | 365 |
403 if (desc.iSerialNumber == 0) { | 366 *serial_number = serial_number_; |
404 return false; | 367 return !serial_number_.empty(); |
405 } | |
406 | |
407 scoped_refptr<UsbDeviceHandle> device_handle = Open(); | |
408 if (device_handle.get()) { | |
409 return device_handle->GetStringDescriptor(desc.iSerialNumber, | |
410 serial_number); | |
411 } | |
412 return false; | |
413 #endif | |
414 } | 368 } |
415 | 369 |
416 void UsbDeviceImpl::OnDisconnect() { | 370 void UsbDeviceImpl::OnDisconnect() { |
417 DCHECK(thread_checker_.CalledOnValidThread()); | 371 DCHECK(thread_checker_.CalledOnValidThread()); |
418 HandlesVector handles; | 372 HandlesVector handles; |
419 swap(handles, handles_); | 373 swap(handles, handles_); |
420 for (HandlesVector::iterator it = handles.begin(); it != handles.end(); ++it) | 374 for (HandlesVector::iterator it = handles.begin(); it != handles.end(); ++it) |
421 (*it)->InternalClose(); | 375 (*it)->InternalClose(); |
422 } | 376 } |
423 | 377 |
| 378 #if !defined(USE_UDEV) |
| 379 void UsbDeviceImpl::CacheStrings() { |
| 380 DCHECK(thread_checker_.CalledOnValidThread()); |
| 381 // This is a non-blocking call as libusb has the descriptor in memory. |
| 382 libusb_device_descriptor desc; |
| 383 const int rv = libusb_get_device_descriptor(platform_device_, &desc); |
| 384 if (rv == LIBUSB_SUCCESS) { |
| 385 scoped_refptr<UsbDeviceHandle> device_handle = Open(); |
| 386 if (device_handle.get()) { |
| 387 if (desc.iManufacturer != 0) { |
| 388 device_handle->GetStringDescriptor(desc.iManufacturer, &manufacturer_); |
| 389 } |
| 390 if (desc.iProduct != 0) { |
| 391 device_handle->GetStringDescriptor(desc.iProduct, &product_); |
| 392 } |
| 393 if (desc.iSerialNumber != 0) { |
| 394 device_handle->GetStringDescriptor(desc.iSerialNumber, &serial_number_); |
| 395 } |
| 396 device_handle->Close(); |
| 397 } else { |
| 398 VLOG(1) << "Failed to open device to cache string descriptors."; |
| 399 } |
| 400 } else { |
| 401 VLOG(1) << "Failed to read device descriptor to cache string descriptors: " |
| 402 << ConvertPlatformUsbErrorToString(rv); |
| 403 } |
| 404 strings_cached_ = true; |
| 405 } |
| 406 #endif // !defined(USE_UDEV) |
| 407 |
424 } // namespace device | 408 } // namespace device |
OLD | NEW |