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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 410 if (!platform_devices) { | 410 if (!platform_devices) { |
| 411 RefreshDevicesComplete(); | 411 RefreshDevicesComplete(); |
| 412 return; | 412 return; |
| 413 } | 413 } |
| 414 | 414 |
| 415 base::Closure refresh_complete = | 415 base::Closure refresh_complete = |
| 416 base::BarrierClosure(static_cast<int>(device_count), | 416 base::BarrierClosure(static_cast<int>(device_count), |
| 417 base::Bind(&UsbServiceImpl::RefreshDevicesComplete, | 417 base::Bind(&UsbServiceImpl::RefreshDevicesComplete, |
| 418 weak_factory_.GetWeakPtr())); | 418 weak_factory_.GetWeakPtr())); |
| 419 std::list<PlatformUsbDevice> new_devices; | 419 std::list<PlatformUsbDevice> new_devices; |
| 420 std::set<PlatformUsbDevice> existing_ignored_devices; | |
| 420 | 421 |
| 421 // Look for new and existing devices. | 422 // Look for new and existing devices. |
| 422 for (size_t i = 0; i < device_count; ++i) { | 423 for (size_t i = 0; i < device_count; ++i) { |
| 423 PlatformUsbDevice platform_device = platform_devices[i]; | 424 PlatformUsbDevice platform_device = platform_devices[i]; |
| 425 // Ignore some devices. | |
| 426 if (ContainsValue(ignored_devices_, platform_device)) { | |
| 427 existing_ignored_devices.insert(platform_device); | |
| 428 refresh_complete.Run(); | |
| 429 continue; | |
| 430 } | |
| 431 | |
| 424 auto it = platform_devices_.find(platform_device); | 432 auto it = platform_devices_.find(platform_device); |
| 425 | 433 |
| 426 if (it == platform_devices_.end()) { | 434 if (it == platform_devices_.end()) { |
| 427 libusb_ref_device(platform_device); | 435 libusb_ref_device(platform_device); |
| 428 new_devices.push_back(platform_device); | 436 new_devices.push_back(platform_device); |
| 429 } else { | 437 } else { |
| 430 it->second->set_visited(true); | 438 it->second->set_visited(true); |
| 431 refresh_complete.Run(); | 439 refresh_complete.Run(); |
| 432 } | 440 } |
| 433 } | 441 } |
| 434 | 442 |
| 435 // Remove devices not seen in this enumeration. | 443 // Remove devices not seen in this enumeration. |
| 436 for (PlatformDeviceMap::iterator it = platform_devices_.begin(); | 444 for (PlatformDeviceMap::iterator it = platform_devices_.begin(); |
| 437 it != platform_devices_.end(); | 445 it != platform_devices_.end(); |
| 438 /* incremented internally */) { | 446 /* incremented internally */) { |
| 439 PlatformDeviceMap::iterator current = it++; | 447 PlatformDeviceMap::iterator current = it++; |
| 440 const scoped_refptr<UsbDeviceImpl>& device = current->second; | 448 const scoped_refptr<UsbDeviceImpl>& device = current->second; |
| 441 if (device->was_visited()) { | 449 if (device->was_visited()) { |
| 442 device->set_visited(false); | 450 device->set_visited(false); |
| 443 } else { | 451 } else { |
| 444 RemoveDevice(device); | 452 RemoveDevice(device); |
| 445 } | 453 } |
| 446 } | 454 } |
| 447 | 455 |
| 456 // Remove devices not seen in this enumeration from |ignored_devices_|. | |
| 457 for (auto it = ignored_devices_.begin(); it != ignored_devices_.end(); | |
| 458 /* incremented internally */) { | |
| 459 auto current = it++; | |
| 460 if (!ContainsValue(existing_ignored_devices, *current)) | |
| 461 ignored_devices_.erase(current); | |
|
Reilly Grant (use Gerrit)
2016/04/22 22:21:24
We should libusb_unref_device here and in the UsbS
juncai
2016/04/26 19:26:44
Done.
Also did some sanity check and found a pote
| |
| 462 } | |
| 463 | |
| 448 for (PlatformUsbDevice platform_device : new_devices) { | 464 for (PlatformUsbDevice platform_device : new_devices) { |
| 449 EnumerateDevice(platform_device, refresh_complete); | 465 EnumerateDevice(platform_device, refresh_complete); |
| 450 } | 466 } |
| 451 | 467 |
| 452 libusb_free_device_list(platform_devices, true); | 468 libusb_free_device_list(platform_devices, true); |
| 453 } | 469 } |
| 454 | 470 |
| 455 void UsbServiceImpl::RefreshDevicesComplete() { | 471 void UsbServiceImpl::RefreshDevicesComplete() { |
| 456 DCHECK(CalledOnValidThread()); | 472 DCHECK(CalledOnValidThread()); |
| 457 DCHECK(enumeration_in_progress_); | 473 DCHECK(enumeration_in_progress_); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 481 void UsbServiceImpl::EnumerateDevice(PlatformUsbDevice platform_device, | 497 void UsbServiceImpl::EnumerateDevice(PlatformUsbDevice platform_device, |
| 482 const base::Closure& refresh_complete) { | 498 const base::Closure& refresh_complete) { |
| 483 DCHECK(context_); | 499 DCHECK(context_); |
| 484 devices_being_enumerated_.insert(platform_device); | 500 devices_being_enumerated_.insert(platform_device); |
| 485 | 501 |
| 486 libusb_device_descriptor descriptor; | 502 libusb_device_descriptor descriptor; |
| 487 int rv = libusb_get_device_descriptor(platform_device, &descriptor); | 503 int rv = libusb_get_device_descriptor(platform_device, &descriptor); |
| 488 if (rv == LIBUSB_SUCCESS) { | 504 if (rv == LIBUSB_SUCCESS) { |
| 489 if (descriptor.bDeviceClass == LIBUSB_CLASS_HUB) { | 505 if (descriptor.bDeviceClass == LIBUSB_CLASS_HUB) { |
| 490 // Don't try to enumerate hubs. We never want to connect to a hub. | 506 // Don't try to enumerate hubs. We never want to connect to a hub. |
| 507 ignored_devices_.insert(platform_device); | |
| 491 refresh_complete.Run(); | 508 refresh_complete.Run(); |
| 492 return; | 509 return; |
| 493 } | 510 } |
| 494 | 511 |
| 495 scoped_refptr<UsbDeviceImpl> device(new UsbDeviceImpl( | 512 scoped_refptr<UsbDeviceImpl> device(new UsbDeviceImpl( |
| 496 context_, platform_device, descriptor, blocking_task_runner_)); | 513 context_, platform_device, descriptor, blocking_task_runner_)); |
| 497 base::Closure add_device = | 514 base::Closure add_device = |
| 498 base::Bind(&UsbServiceImpl::AddDevice, weak_factory_.GetWeakPtr(), | 515 base::Bind(&UsbServiceImpl::AddDevice, weak_factory_.GetWeakPtr(), |
| 499 refresh_complete, device); | 516 refresh_complete, device); |
| 517 base::Closure enumeration_failed = base::Bind( | |
| 518 &UsbServiceImpl::EnumerationFailed, weak_factory_.GetWeakPtr(), | |
| 519 platform_device, refresh_complete); | |
| 500 bool read_bos_descriptors = descriptor.bcdUSB >= kUsbVersion2_1; | 520 bool read_bos_descriptors = descriptor.bcdUSB >= kUsbVersion2_1; |
| 501 | 521 |
| 502 #if defined(USE_UDEV) | 522 #if defined(USE_UDEV) |
| 503 blocking_task_runner_->PostTask( | 523 blocking_task_runner_->PostTask( |
| 504 FROM_HERE, | 524 FROM_HERE, |
| 505 base::Bind(&EnumerateUdevDevice, device, read_bos_descriptors, | 525 base::Bind(&EnumerateUdevDevice, device, read_bos_descriptors, |
| 506 task_runner_, add_device, refresh_complete)); | 526 task_runner_, add_device, enumeration_failed)); |
| 507 #else | 527 #else |
| 508 if (descriptor.iManufacturer == 0 && descriptor.iProduct == 0 && | 528 if (descriptor.iManufacturer == 0 && descriptor.iProduct == 0 && |
| 509 descriptor.iSerialNumber == 0 && !read_bos_descriptors) { | 529 descriptor.iSerialNumber == 0 && !read_bos_descriptors) { |
| 510 // Don't bother disturbing the device if it has no descriptors to offer. | 530 // Don't bother disturbing the device if it has no descriptors to offer. |
| 511 add_device.Run(); | 531 add_device.Run(); |
| 512 } else { | 532 } else { |
| 513 device->Open(base::Bind(&OnDeviceOpenedReadDescriptors, | 533 device->Open(base::Bind(&OnDeviceOpenedReadDescriptors, |
| 514 descriptor.iManufacturer, descriptor.iProduct, | 534 descriptor.iManufacturer, descriptor.iProduct, |
| 515 descriptor.iSerialNumber, read_bos_descriptors, | 535 descriptor.iSerialNumber, read_bos_descriptors, |
| 516 add_device, refresh_complete)); | 536 add_device, enumeration_failed)); |
| 517 } | 537 } |
| 518 #endif | 538 #endif |
| 519 } else { | 539 } else { |
| 520 USB_LOG(EVENT) << "Failed to get device descriptor: " | 540 USB_LOG(EVENT) << "Failed to get device descriptor: " |
| 521 << ConvertPlatformUsbErrorToString(rv); | 541 << ConvertPlatformUsbErrorToString(rv); |
| 522 refresh_complete.Run(); | 542 refresh_complete.Run(); |
| 523 } | 543 } |
| 524 } | 544 } |
| 525 | 545 |
| 526 void UsbServiceImpl::AddDevice(const base::Closure& refresh_complete, | 546 void UsbServiceImpl::AddDevice(const base::Closure& refresh_complete, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 609 DCHECK(CalledOnValidThread()); | 629 DCHECK(CalledOnValidThread()); |
| 610 PlatformDeviceMap::iterator it = platform_devices_.find(platform_device); | 630 PlatformDeviceMap::iterator it = platform_devices_.find(platform_device); |
| 611 if (it != platform_devices_.end()) { | 631 if (it != platform_devices_.end()) { |
| 612 RemoveDevice(it->second); | 632 RemoveDevice(it->second); |
| 613 } else { | 633 } else { |
| 614 devices_being_enumerated_.erase(platform_device); | 634 devices_being_enumerated_.erase(platform_device); |
| 615 } | 635 } |
| 616 libusb_unref_device(platform_device); | 636 libusb_unref_device(platform_device); |
| 617 } | 637 } |
| 618 | 638 |
| 639 void UsbServiceImpl::EnumerationFailed(PlatformUsbDevice platform_device, | |
| 640 const base::Closure& refresh_complete) { | |
| 641 libusb_ref_device(platform_device); | |
| 642 ignored_devices_.insert(platform_device); | |
| 643 refresh_complete.Run(); | |
| 644 } | |
| 645 | |
| 619 } // namespace device | 646 } // namespace device |
| OLD | NEW |