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_service_impl.h" | 5 #include "device/usb/usb_service_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <list> | 9 #include <list> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 barrier.Run(); | 151 barrier.Run(); |
| 152 } | 152 } |
| 153 | 153 |
| 154 void OnDeviceOpenedReadDescriptors( | 154 void OnDeviceOpenedReadDescriptors( |
| 155 uint8_t manufacturer, | 155 uint8_t manufacturer, |
| 156 uint8_t product, | 156 uint8_t product, |
| 157 uint8_t serial_number, | 157 uint8_t serial_number, |
| 158 bool read_bos_descriptors, | 158 bool read_bos_descriptors, |
| 159 const base::Closure& success_closure, | 159 const base::Closure& success_closure, |
| 160 const base::Closure& failure_closure, | 160 const base::Closure& failure_closure, |
| 161 const base::Closure& add_ignored_device_closure, | |
| 161 scoped_refptr<UsbDeviceHandle> device_handle) { | 162 scoped_refptr<UsbDeviceHandle> device_handle) { |
| 162 if (device_handle) { | 163 if (device_handle) { |
| 163 std::unique_ptr<std::map<uint8_t, base::string16>> string_map( | 164 std::unique_ptr<std::map<uint8_t, base::string16>> string_map( |
| 164 new std::map<uint8_t, base::string16>()); | 165 new std::map<uint8_t, base::string16>()); |
| 165 if (manufacturer != 0) | 166 if (manufacturer != 0) |
| 166 (*string_map)[manufacturer] = base::string16(); | 167 (*string_map)[manufacturer] = base::string16(); |
| 167 if (product != 0) | 168 if (product != 0) |
| 168 (*string_map)[product] = base::string16(); | 169 (*string_map)[product] = base::string16(); |
| 169 if (serial_number != 0) | 170 if (serial_number != 0) |
| 170 (*string_map)[serial_number] = base::string16(); | 171 (*string_map)[serial_number] = base::string16(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 188 device_handle, std::move(string_map), | 189 device_handle, std::move(string_map), |
| 189 base::Bind(&SaveStringsAndRunContinuation, device, manufacturer, | 190 base::Bind(&SaveStringsAndRunContinuation, device, manufacturer, |
| 190 product, serial_number, barrier)); | 191 product, serial_number, barrier)); |
| 191 } | 192 } |
| 192 | 193 |
| 193 if (read_bos_descriptors) { | 194 if (read_bos_descriptors) { |
| 194 ReadWebUsbDescriptors(device_handle, base::Bind(&OnReadBosDescriptor, | 195 ReadWebUsbDescriptors(device_handle, base::Bind(&OnReadBosDescriptor, |
| 195 device_handle, barrier)); | 196 device_handle, barrier)); |
| 196 } | 197 } |
| 197 } else { | 198 } else { |
| 199 add_ignored_device_closure.Run(); | |
| 198 failure_closure.Run(); | 200 failure_closure.Run(); |
| 199 } | 201 } |
| 200 } | 202 } |
| 201 | 203 |
| 202 #if defined(USE_UDEV) | 204 #if defined(USE_UDEV) |
| 203 | 205 |
| 204 void EnumerateUdevDevice(scoped_refptr<UsbDeviceImpl> device, | 206 void EnumerateUdevDevice(scoped_refptr<UsbDeviceImpl> device, |
| 205 bool read_bos_descriptors, | 207 bool read_bos_descriptors, |
| 206 scoped_refptr<base::SequencedTaskRunner> task_runner, | 208 scoped_refptr<base::SequencedTaskRunner> task_runner, |
| 207 const base::Closure& success_closure, | 209 const base::Closure& success_closure, |
| 208 const base::Closure& failure_closure) { | 210 const base::Closure& failure_closure, |
| 211 const base::Closure& add_ignored_device_closure) { | |
| 209 ScopedUdevPtr udev(udev_new()); | 212 ScopedUdevPtr udev(udev_new()); |
| 210 ScopedUdevEnumeratePtr udev_enumerate(udev_enumerate_new(udev.get())); | 213 ScopedUdevEnumeratePtr udev_enumerate(udev_enumerate_new(udev.get())); |
| 211 | 214 |
| 212 udev_enumerate_add_match_subsystem(udev_enumerate.get(), "usb"); | 215 udev_enumerate_add_match_subsystem(udev_enumerate.get(), "usb"); |
| 213 if (udev_enumerate_scan_devices(udev_enumerate.get()) != 0) { | 216 if (udev_enumerate_scan_devices(udev_enumerate.get()) != 0) { |
| 214 task_runner->PostTask(FROM_HERE, failure_closure); | 217 task_runner->PostTask(FROM_HERE, failure_closure); |
| 215 return; | 218 return; |
| 216 } | 219 } |
| 217 | 220 |
| 218 std::string bus_number = | 221 std::string bus_number = |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 | 254 |
| 252 value = udev_device_get_devnode(udev_device.get()); | 255 value = udev_device_get_devnode(udev_device.get()); |
| 253 if (value) { | 256 if (value) { |
| 254 device->set_device_path(value); | 257 device->set_device_path(value); |
| 255 | 258 |
| 256 if (read_bos_descriptors) { | 259 if (read_bos_descriptors) { |
| 257 task_runner->PostTask( | 260 task_runner->PostTask( |
| 258 FROM_HERE, | 261 FROM_HERE, |
| 259 base::Bind(&UsbDevice::Open, device, | 262 base::Bind(&UsbDevice::Open, device, |
| 260 base::Bind(&OnDeviceOpenedReadDescriptors, 0, 0, 0, | 263 base::Bind(&OnDeviceOpenedReadDescriptors, 0, 0, 0, |
| 261 true, success_closure, failure_closure))); | 264 true, success_closure, failure_closure, |
| 265 add_ignored_device_closure))); | |
| 262 } else { | 266 } else { |
| 263 task_runner->PostTask(FROM_HERE, success_closure); | 267 task_runner->PostTask(FROM_HERE, success_closure); |
| 264 } | 268 } |
| 265 return; | 269 return; |
| 266 } | 270 } |
| 267 | 271 |
| 268 break; | 272 break; |
| 269 } | 273 } |
| 270 } | 274 } |
| 271 | 275 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 410 if (!platform_devices) { | 414 if (!platform_devices) { |
| 411 RefreshDevicesComplete(); | 415 RefreshDevicesComplete(); |
| 412 return; | 416 return; |
| 413 } | 417 } |
| 414 | 418 |
| 415 base::Closure refresh_complete = | 419 base::Closure refresh_complete = |
| 416 base::BarrierClosure(static_cast<int>(device_count), | 420 base::BarrierClosure(static_cast<int>(device_count), |
| 417 base::Bind(&UsbServiceImpl::RefreshDevicesComplete, | 421 base::Bind(&UsbServiceImpl::RefreshDevicesComplete, |
| 418 weak_factory_.GetWeakPtr())); | 422 weak_factory_.GetWeakPtr())); |
| 419 std::list<PlatformUsbDevice> new_devices; | 423 std::list<PlatformUsbDevice> new_devices; |
| 424 std::set<PlatformUsbDevice> existing_ignored_devices; | |
| 420 | 425 |
| 421 // Look for new and existing devices. | 426 // Look for new and existing devices. |
| 422 for (size_t i = 0; i < device_count; ++i) { | 427 for (size_t i = 0; i < device_count; ++i) { |
| 423 PlatformUsbDevice platform_device = platform_devices[i]; | 428 PlatformUsbDevice platform_device = platform_devices[i]; |
| 429 // Ignore some devices. | |
| 430 if (ignored_devices_.find(platform_device) != ignored_devices_.end()) { | |
|
Reilly Grant (use Gerrit)
2016/04/22 21:12:04
if (ContainsValue(ignored_devices, platform_device
juncai
2016/04/22 22:02:43
Done.
| |
| 431 existing_ignored_devices.insert(platform_device); | |
| 432 refresh_complete.Run(); | |
| 433 continue; | |
| 434 } | |
| 435 | |
| 424 auto it = platform_devices_.find(platform_device); | 436 auto it = platform_devices_.find(platform_device); |
| 425 | 437 |
| 426 if (it == platform_devices_.end()) { | 438 if (it == platform_devices_.end()) { |
| 427 libusb_ref_device(platform_device); | 439 libusb_ref_device(platform_device); |
| 428 new_devices.push_back(platform_device); | 440 new_devices.push_back(platform_device); |
| 429 } else { | 441 } else { |
| 430 it->second->set_visited(true); | 442 it->second->set_visited(true); |
| 431 refresh_complete.Run(); | 443 refresh_complete.Run(); |
| 432 } | 444 } |
| 433 } | 445 } |
| 434 | 446 |
| 435 // Remove devices not seen in this enumeration. | 447 // Remove devices not seen in this enumeration. |
| 436 for (PlatformDeviceMap::iterator it = platform_devices_.begin(); | 448 for (PlatformDeviceMap::iterator it = platform_devices_.begin(); |
| 437 it != platform_devices_.end(); | 449 it != platform_devices_.end(); |
| 438 /* incremented internally */) { | 450 /* incremented internally */) { |
| 439 PlatformDeviceMap::iterator current = it++; | 451 PlatformDeviceMap::iterator current = it++; |
| 440 const scoped_refptr<UsbDeviceImpl>& device = current->second; | 452 const scoped_refptr<UsbDeviceImpl>& device = current->second; |
| 441 if (device->was_visited()) { | 453 if (device->was_visited()) { |
| 442 device->set_visited(false); | 454 device->set_visited(false); |
| 443 } else { | 455 } else { |
| 444 RemoveDevice(device); | 456 RemoveDevice(device); |
| 445 } | 457 } |
| 446 } | 458 } |
| 447 | 459 |
| 460 // Remove devices not seen in this enumeration from |ignored_devices_|. | |
| 461 for (auto it = ignored_devices_.begin(); it != ignored_devices_.end(); | |
| 462 /* incremented internally */) { | |
| 463 auto current = it++; | |
| 464 if (existing_ignored_devices.find(*current) == | |
| 465 existing_ignored_devices.end()) | |
|
Reilly Grant (use Gerrit)
2016/04/22 21:12:04
if (!ContainsValue(existing_ignore_devices, *curre
juncai
2016/04/22 22:02:43
Done.
| |
| 466 ignored_devices_.erase(current); | |
| 467 } | |
| 468 | |
| 448 for (PlatformUsbDevice platform_device : new_devices) { | 469 for (PlatformUsbDevice platform_device : new_devices) { |
| 449 EnumerateDevice(platform_device, refresh_complete); | 470 EnumerateDevice(platform_device, refresh_complete); |
| 450 } | 471 } |
| 451 | 472 |
| 452 libusb_free_device_list(platform_devices, true); | 473 libusb_free_device_list(platform_devices, true); |
| 453 } | 474 } |
| 454 | 475 |
| 455 void UsbServiceImpl::RefreshDevicesComplete() { | 476 void UsbServiceImpl::RefreshDevicesComplete() { |
| 456 DCHECK(CalledOnValidThread()); | 477 DCHECK(CalledOnValidThread()); |
| 457 DCHECK(enumeration_in_progress_); | 478 DCHECK(enumeration_in_progress_); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 481 void UsbServiceImpl::EnumerateDevice(PlatformUsbDevice platform_device, | 502 void UsbServiceImpl::EnumerateDevice(PlatformUsbDevice platform_device, |
| 482 const base::Closure& refresh_complete) { | 503 const base::Closure& refresh_complete) { |
| 483 DCHECK(context_); | 504 DCHECK(context_); |
| 484 devices_being_enumerated_.insert(platform_device); | 505 devices_being_enumerated_.insert(platform_device); |
| 485 | 506 |
| 486 libusb_device_descriptor descriptor; | 507 libusb_device_descriptor descriptor; |
| 487 int rv = libusb_get_device_descriptor(platform_device, &descriptor); | 508 int rv = libusb_get_device_descriptor(platform_device, &descriptor); |
| 488 if (rv == LIBUSB_SUCCESS) { | 509 if (rv == LIBUSB_SUCCESS) { |
| 489 if (descriptor.bDeviceClass == LIBUSB_CLASS_HUB) { | 510 if (descriptor.bDeviceClass == LIBUSB_CLASS_HUB) { |
| 490 // Don't try to enumerate hubs. We never want to connect to a hub. | 511 // Don't try to enumerate hubs. We never want to connect to a hub. |
| 512 ignored_devices_.insert(platform_device); | |
| 491 refresh_complete.Run(); | 513 refresh_complete.Run(); |
| 492 return; | 514 return; |
| 493 } | 515 } |
| 494 | 516 |
| 495 scoped_refptr<UsbDeviceImpl> device(new UsbDeviceImpl( | 517 scoped_refptr<UsbDeviceImpl> device(new UsbDeviceImpl( |
| 496 context_, platform_device, descriptor, blocking_task_runner_)); | 518 context_, platform_device, descriptor, blocking_task_runner_)); |
| 497 base::Closure add_device = | 519 base::Closure add_device = |
| 498 base::Bind(&UsbServiceImpl::AddDevice, weak_factory_.GetWeakPtr(), | 520 base::Bind(&UsbServiceImpl::AddDevice, weak_factory_.GetWeakPtr(), |
| 499 refresh_complete, device); | 521 refresh_complete, device); |
| 522 base::Closure add_ignored_device = | |
| 523 base::Bind(&UsbServiceImpl::AddIgnoredDevice, | |
| 524 weak_factory_.GetWeakPtr(), platform_device); | |
| 500 bool read_bos_descriptors = descriptor.bcdUSB >= kUsbVersion2_1; | 525 bool read_bos_descriptors = descriptor.bcdUSB >= kUsbVersion2_1; |
| 501 | 526 |
| 502 #if defined(USE_UDEV) | 527 #if defined(USE_UDEV) |
| 503 blocking_task_runner_->PostTask( | 528 blocking_task_runner_->PostTask( |
| 504 FROM_HERE, | 529 FROM_HERE, base::Bind(&EnumerateUdevDevice, device, |
| 505 base::Bind(&EnumerateUdevDevice, device, read_bos_descriptors, | 530 read_bos_descriptors, task_runner_, add_device, |
| 506 task_runner_, add_device, refresh_complete)); | 531 refresh_complete, add_ignored_device)); |
|
Reilly Grant (use Gerrit)
2016/04/22 21:12:04
Instead of passing 3 callbacks here can we just pa
juncai
2016/04/22 22:02:43
Done.
| |
| 507 #else | 532 #else |
| 508 if (descriptor.iManufacturer == 0 && descriptor.iProduct == 0 && | 533 if (descriptor.iManufacturer == 0 && descriptor.iProduct == 0 && |
| 509 descriptor.iSerialNumber == 0 && !read_bos_descriptors) { | 534 descriptor.iSerialNumber == 0 && !read_bos_descriptors) { |
| 510 // Don't bother disturbing the device if it has no descriptors to offer. | 535 // Don't bother disturbing the device if it has no descriptors to offer. |
| 511 add_device.Run(); | 536 add_device.Run(); |
| 512 } else { | 537 } else { |
| 513 device->Open(base::Bind(&OnDeviceOpenedReadDescriptors, | 538 device->Open(base::Bind( |
| 514 descriptor.iManufacturer, descriptor.iProduct, | 539 &OnDeviceOpenedReadDescriptors, descriptor.iManufacturer, |
| 515 descriptor.iSerialNumber, read_bos_descriptors, | 540 descriptor.iProduct, descriptor.iSerialNumber, read_bos_descriptors, |
| 516 add_device, refresh_complete)); | 541 add_device, refresh_complete, add_ignored_device)); |
| 517 } | 542 } |
| 518 #endif | 543 #endif |
| 519 } else { | 544 } else { |
| 520 USB_LOG(EVENT) << "Failed to get device descriptor: " | 545 USB_LOG(EVENT) << "Failed to get device descriptor: " |
| 521 << ConvertPlatformUsbErrorToString(rv); | 546 << ConvertPlatformUsbErrorToString(rv); |
| 522 refresh_complete.Run(); | 547 refresh_complete.Run(); |
| 523 } | 548 } |
| 524 } | 549 } |
| 525 | 550 |
| 526 void UsbServiceImpl::AddDevice(const base::Closure& refresh_complete, | 551 void UsbServiceImpl::AddDevice(const base::Closure& refresh_complete, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 609 DCHECK(CalledOnValidThread()); | 634 DCHECK(CalledOnValidThread()); |
| 610 PlatformDeviceMap::iterator it = platform_devices_.find(platform_device); | 635 PlatformDeviceMap::iterator it = platform_devices_.find(platform_device); |
| 611 if (it != platform_devices_.end()) { | 636 if (it != platform_devices_.end()) { |
| 612 RemoveDevice(it->second); | 637 RemoveDevice(it->second); |
| 613 } else { | 638 } else { |
| 614 devices_being_enumerated_.erase(platform_device); | 639 devices_being_enumerated_.erase(platform_device); |
| 615 } | 640 } |
| 616 libusb_unref_device(platform_device); | 641 libusb_unref_device(platform_device); |
| 617 } | 642 } |
| 618 | 643 |
| 644 void UsbServiceImpl::AddIgnoredDevice(PlatformUsbDevice platform_device) { | |
| 645 ignored_devices_.insert(platform_device); | |
|
Reilly Grant (use Gerrit)
2016/04/22 21:12:04
We should probably call libusb_ref_device(platform
juncai
2016/04/22 22:02:43
Done.
| |
| 646 } | |
| 647 | |
| 619 } // namespace device | 648 } // namespace device |
| OLD | NEW |