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

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 comment 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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