Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: device/usb/usb_service_impl.cc

Issue 1903933002: Store devices that only need to be enumerated once (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address reillyg@'s comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/usb/usb_service_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « device/usb/usb_service_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698