Chromium Code Reviews| 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" |
| 11 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/strings/string_number_conversions.h" | |
| 14 #include "base/strings/utf_string_conversions.h" | |
| 13 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
| 14 #include "device/usb/usb_context.h" | 16 #include "device/usb/usb_context.h" |
| 15 #include "device/usb/usb_descriptors.h" | 17 #include "device/usb/usb_descriptors.h" |
| 16 #include "device/usb/usb_device_handle_impl.h" | 18 #include "device/usb/usb_device_handle_impl.h" |
| 17 #include "device/usb/usb_error.h" | 19 #include "device/usb/usb_error.h" |
| 18 #include "third_party/libusb/src/libusb/libusb.h" | 20 #include "third_party/libusb/src/libusb/libusb.h" |
| 19 | 21 |
| 20 #if defined(OS_CHROMEOS) | 22 #if defined(OS_CHROMEOS) |
| 21 #include "base/sys_info.h" | 23 #include "base/sys_info.h" |
| 22 #include "chromeos/dbus/dbus_thread_manager.h" | 24 #include "chromeos/dbus/dbus_thread_manager.h" |
| 23 #include "chromeos/dbus/permission_broker_client.h" | 25 #include "chromeos/dbus/permission_broker_client.h" |
| 24 #endif // defined(OS_CHROMEOS) | 26 #endif // defined(OS_CHROMEOS) |
| 25 | 27 |
| 28 #if defined(OS_LINUX) | |
| 29 #include "device/udev_linux/udev.h" | |
| 30 #endif // defined(OS_LINUX) | |
| 31 | |
| 26 namespace device { | 32 namespace device { |
| 27 | 33 |
| 28 namespace { | 34 namespace { |
| 29 | 35 |
| 30 #if defined(OS_CHROMEOS) | 36 #if defined(OS_CHROMEOS) |
| 31 void OnRequestUsbAccessReplied( | 37 void OnRequestUsbAccessReplied( |
| 32 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 38 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 33 const base::Callback<void(bool success)>& callback, | 39 const base::Callback<void(bool success)>& callback, |
| 34 bool success) { | 40 bool success) { |
| 35 task_runner->PostTask(FROM_HERE, base::Bind(callback, success)); | 41 task_runner->PostTask(FROM_HERE, base::Bind(callback, success)); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 uint16 vendor_id, | 122 uint16 vendor_id, |
| 117 uint16 product_id, | 123 uint16 product_id, |
| 118 uint32 unique_id) | 124 uint32 unique_id) |
| 119 : UsbDevice(vendor_id, product_id, unique_id), | 125 : UsbDevice(vendor_id, product_id, unique_id), |
| 120 platform_device_(platform_device), | 126 platform_device_(platform_device), |
| 121 current_configuration_cached_(false), | 127 current_configuration_cached_(false), |
| 122 context_(context), | 128 context_(context), |
| 123 ui_task_runner_(ui_task_runner) { | 129 ui_task_runner_(ui_task_runner) { |
| 124 CHECK(platform_device) << "platform_device cannot be NULL"; | 130 CHECK(platform_device) << "platform_device cannot be NULL"; |
| 125 libusb_ref_device(platform_device); | 131 libusb_ref_device(platform_device); |
| 132 | |
| 133 #if defined(OS_LINUX) | |
| 134 ScopedUdevPtr udev(udev_new()); | |
| 135 ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev.get())); | |
| 136 | |
| 137 udev_enumerate_add_match_subsystem(enumerate.get(), "usb"); | |
| 138 if (udev_enumerate_scan_devices(enumerate.get()) != 0) { | |
| 139 return; | |
| 140 } | |
| 141 std::string bus_number = | |
| 142 base::IntToString(libusb_get_bus_number(platform_device)); | |
| 143 std::string device_address = | |
| 144 base::IntToString(libusb_get_device_address(platform_device)); | |
| 145 udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate.get()); | |
| 146 for (udev_list_entry* i = devices; i != NULL; | |
| 147 i = udev_list_entry_get_next(i)) { | |
| 148 ScopedUdevDevicePtr device( | |
| 149 udev_device_new_from_syspath(udev.get(), udev_list_entry_get_name(i))); | |
| 150 if (device) { | |
| 151 const char* value = udev_device_get_sysattr_value(device.get(), "busnum"); | |
| 152 if (!value || bus_number != value) { | |
| 153 continue; | |
| 154 } | |
| 155 value = udev_device_get_sysattr_value(device.get(), "devnum"); | |
| 156 if (!value || device_address != value) { | |
| 157 continue; | |
| 158 } | |
| 159 | |
| 160 value = udev_device_get_sysattr_value(device.get(), "manufacturer"); | |
| 161 manufacturer_ = value ? value : ""; | |
| 162 value = udev_device_get_sysattr_value(device.get(), "product"); | |
| 163 product_ = value ? value : ""; | |
| 164 value = udev_device_get_sysattr_value(device.get(), "serial"); | |
| 165 serial_number_ = value ? value : ""; | |
| 166 break; | |
| 167 } | |
| 168 } | |
| 169 #endif | |
| 126 } | 170 } |
| 127 | 171 |
| 128 UsbDeviceImpl::~UsbDeviceImpl() { | 172 UsbDeviceImpl::~UsbDeviceImpl() { |
| 129 DCHECK(thread_checker_.CalledOnValidThread()); | 173 DCHECK(thread_checker_.CalledOnValidThread()); |
| 130 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end(); | 174 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end(); |
| 131 ++it) { | 175 ++it) { |
| 132 (*it)->InternalClose(); | 176 (*it)->InternalClose(); |
| 133 } | 177 } |
| 134 STLClearObject(&handles_); | 178 STLClearObject(&handles_); |
| 135 libusb_unref_device(platform_device_); | 179 libusb_unref_device(platform_device_); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 268 platform_config->extra, | 312 platform_config->extra, |
| 269 platform_config->extra + platform_config->extra_length); | 313 platform_config->extra + platform_config->extra_length); |
| 270 | 314 |
| 271 libusb_free_config_descriptor(platform_config); | 315 libusb_free_config_descriptor(platform_config); |
| 272 current_configuration_cached_ = true; | 316 current_configuration_cached_ = true; |
| 273 } | 317 } |
| 274 | 318 |
| 275 return current_configuration_; | 319 return current_configuration_; |
| 276 } | 320 } |
| 277 | 321 |
| 322 bool UsbDeviceImpl::GetManufacturer(base::string16* manufacturer) { | |
| 323 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 324 | |
| 325 #if defined(OS_LINUX) | |
| 326 if (manufacturer_.empty()) { | |
|
scheib
2014/09/25 17:36:04
Consider caching into manufacturer_ on all platfor
Reilly Grant (use Gerrit)
2014/09/25 17:58:44
GetStringDescriptor caches for the other platforms
| |
| 327 return false; | |
| 328 } | |
| 329 *manufacturer = base::UTF8ToUTF16(manufacturer_); | |
| 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 | |
| 341 if (desc.iManufacturer == 0) { | |
| 342 return false; | |
| 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 } | |
| 352 | |
| 353 bool UsbDeviceImpl::GetProduct(base::string16* product) { | |
| 354 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 355 | |
| 356 #if defined(OS_LINUX) | |
| 357 if (product_.empty()) { | |
| 358 return false; | |
| 359 } | |
| 360 *product = base::UTF8ToUTF16(product_); | |
| 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 | |
| 372 if (desc.iProduct == 0) { | |
| 373 return false; | |
| 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 } | |
| 383 | |
| 384 bool UsbDeviceImpl::GetSerialNumber(base::string16* serial_number) { | |
| 385 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 386 | |
| 387 #if defined(OS_LINUX) | |
| 388 if (serial_number_.empty()) { | |
| 389 return false; | |
| 390 } | |
| 391 *serial_number = base::UTF8ToUTF16(serial_number_); | |
| 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 | |
| 403 if (desc.iSerialNumber == 0) { | |
| 404 return false; | |
| 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 } | |
| 415 | |
| 278 void UsbDeviceImpl::OnDisconnect() { | 416 void UsbDeviceImpl::OnDisconnect() { |
| 279 DCHECK(thread_checker_.CalledOnValidThread()); | 417 DCHECK(thread_checker_.CalledOnValidThread()); |
| 280 HandlesVector handles; | 418 HandlesVector handles; |
| 281 swap(handles, handles_); | 419 swap(handles, handles_); |
| 282 for (HandlesVector::iterator it = handles.begin(); it != handles.end(); ++it) | 420 for (HandlesVector::iterator it = handles.begin(); it != handles.end(); ++it) |
| 283 (*it)->InternalClose(); | 421 (*it)->InternalClose(); |
| 284 } | 422 } |
| 285 | 423 |
| 286 } // namespace device | 424 } // namespace device |
| OLD | NEW |