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