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_device_impl.h" | 5 #include "device/usb/usb_device_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 case LIBUSB_ISO_USAGE_TYPE_IMPLICIT: | 97 case LIBUSB_ISO_USAGE_TYPE_IMPLICIT: |
98 return USB_USAGE_EXPLICIT_FEEDBACK; | 98 return USB_USAGE_EXPLICIT_FEEDBACK; |
99 default: | 99 default: |
100 NOTREACHED(); | 100 NOTREACHED(); |
101 return USB_USAGE_DATA; | 101 return USB_USAGE_DATA; |
102 } | 102 } |
103 } | 103 } |
104 | 104 |
105 } // namespace | 105 } // namespace |
106 | 106 |
107 UsbDevice::UsbDevice(uint16 vendor_id, uint16 product_id, uint32 unique_id) | |
108 : vendor_id_(vendor_id), product_id_(product_id), unique_id_(unique_id) { | |
109 } | |
110 | |
111 UsbDevice::~UsbDevice() { | |
112 } | |
113 | |
114 void UsbDevice::NotifyDisconnect() { | |
115 FOR_EACH_OBSERVER(Observer, observer_list_, OnDisconnect(this)); | |
116 } | |
117 | |
118 UsbDeviceImpl::UsbDeviceImpl( | 107 UsbDeviceImpl::UsbDeviceImpl( |
119 scoped_refptr<UsbContext> context, | 108 scoped_refptr<UsbContext> context, |
120 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, | 109 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
121 PlatformUsbDevice platform_device, | 110 PlatformUsbDevice platform_device, |
122 uint16 vendor_id, | 111 uint16 vendor_id, |
123 uint16 product_id, | 112 uint16 product_id, |
124 uint32 unique_id) | 113 uint32 unique_id) |
125 : UsbDevice(vendor_id, product_id, unique_id), | 114 : UsbDevice(vendor_id, product_id, unique_id), |
126 platform_device_(platform_device), | 115 platform_device_(platform_device), |
127 current_configuration_cached_(false), | 116 current_configuration_cached_(false), |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 } | 166 } |
178 break; | 167 break; |
179 } | 168 } |
180 } | 169 } |
181 #else | 170 #else |
182 strings_cached_ = false; | 171 strings_cached_ = false; |
183 #endif | 172 #endif |
184 } | 173 } |
185 | 174 |
186 UsbDeviceImpl::~UsbDeviceImpl() { | 175 UsbDeviceImpl::~UsbDeviceImpl() { |
187 DCHECK(thread_checker_.CalledOnValidThread()); | 176 // The destructor must be safe to call from any thread. |
188 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end(); | |
189 ++it) { | |
190 (*it)->InternalClose(); | |
191 } | |
192 STLClearObject(&handles_); | |
193 libusb_unref_device(platform_device_); | 177 libusb_unref_device(platform_device_); |
194 } | 178 } |
195 | 179 |
196 #if defined(OS_CHROMEOS) | 180 #if defined(OS_CHROMEOS) |
197 | 181 |
198 void UsbDeviceImpl::RequestUsbAccess( | 182 void UsbDeviceImpl::RequestUsbAccess( |
199 int interface_id, | 183 int interface_id, |
200 const base::Callback<void(bool success)>& callback) { | 184 const base::Callback<void(bool success)>& callback) { |
201 DCHECK(thread_checker_.CalledOnValidThread()); | 185 DCHECK(thread_checker_.CalledOnValidThread()); |
202 | 186 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 CacheStrings(); | 354 CacheStrings(); |
371 } | 355 } |
372 #endif | 356 #endif |
373 | 357 |
374 *serial_number = serial_number_; | 358 *serial_number = serial_number_; |
375 return !serial_number_.empty(); | 359 return !serial_number_.empty(); |
376 } | 360 } |
377 | 361 |
378 void UsbDeviceImpl::OnDisconnect() { | 362 void UsbDeviceImpl::OnDisconnect() { |
379 DCHECK(thread_checker_.CalledOnValidThread()); | 363 DCHECK(thread_checker_.CalledOnValidThread()); |
| 364 |
| 365 // Swap the list of handles into a local variable because closing all open |
| 366 // handles may release the last reference to this object. |
380 HandlesVector handles; | 367 HandlesVector handles; |
381 swap(handles, handles_); | 368 swap(handles, handles_); |
382 for (HandlesVector::iterator it = handles.begin(); it != handles.end(); ++it) | 369 |
383 (*it)->InternalClose(); | 370 for (const scoped_refptr<UsbDeviceHandleImpl>& handle : handles_) { |
| 371 handle->InternalClose(); |
| 372 } |
384 } | 373 } |
385 | 374 |
386 #if !defined(USE_UDEV) | 375 #if !defined(USE_UDEV) |
387 void UsbDeviceImpl::CacheStrings() { | 376 void UsbDeviceImpl::CacheStrings() { |
388 DCHECK(thread_checker_.CalledOnValidThread()); | 377 DCHECK(thread_checker_.CalledOnValidThread()); |
389 // This is a non-blocking call as libusb has the descriptor in memory. | 378 // This is a non-blocking call as libusb has the descriptor in memory. |
390 libusb_device_descriptor desc; | 379 libusb_device_descriptor desc; |
391 const int rv = libusb_get_device_descriptor(platform_device_, &desc); | 380 const int rv = libusb_get_device_descriptor(platform_device_, &desc); |
392 if (rv == LIBUSB_SUCCESS) { | 381 if (rv == LIBUSB_SUCCESS) { |
393 scoped_refptr<UsbDeviceHandle> device_handle = Open(); | 382 scoped_refptr<UsbDeviceHandle> device_handle = Open(); |
(...skipping 13 matching lines...) Expand all Loading... |
407 } | 396 } |
408 } else { | 397 } else { |
409 VLOG(1) << "Failed to read device descriptor to cache string descriptors: " | 398 VLOG(1) << "Failed to read device descriptor to cache string descriptors: " |
410 << ConvertPlatformUsbErrorToString(rv); | 399 << ConvertPlatformUsbErrorToString(rv); |
411 } | 400 } |
412 strings_cached_ = true; | 401 strings_cached_ = true; |
413 } | 402 } |
414 #endif // !defined(USE_UDEV) | 403 #endif // !defined(USE_UDEV) |
415 | 404 |
416 } // namespace device | 405 } // namespace device |
OLD | NEW |