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_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" |
| 11 #include "base/sequenced_task_runner.h" | 11 #include "base/sequenced_task_runner.h" |
| 12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/thread_task_runner_handle.h" | 14 #include "base/thread_task_runner_handle.h" |
| 15 #include "components/device_event_log/device_event_log.h" | 15 #include "components/device_event_log/device_event_log.h" |
| 16 #include "device/usb/usb_context.h" | 16 #include "device/usb/usb_context.h" |
| 17 #include "device/usb/usb_descriptors.h" | |
| 18 #include "device/usb/usb_device_handle_impl.h" | 17 #include "device/usb/usb_device_handle_impl.h" |
| 19 #include "device/usb/usb_error.h" | 18 #include "device/usb/usb_error.h" |
| 20 #include "third_party/libusb/src/libusb/libusb.h" | 19 #include "third_party/libusb/src/libusb/libusb.h" |
| 21 | 20 |
| 22 #if defined(OS_CHROMEOS) | 21 #if defined(OS_CHROMEOS) |
| 23 #include "chromeos/dbus/dbus_thread_manager.h" | 22 #include "chromeos/dbus/dbus_thread_manager.h" |
| 24 #include "chromeos/dbus/permission_broker_client.h" | 23 #include "chromeos/dbus/permission_broker_client.h" |
| 25 #include "dbus/file_descriptor.h" | 24 #include "dbus/file_descriptor.h" |
| 26 #endif // defined(OS_CHROMEOS) | 25 #endif // defined(OS_CHROMEOS) |
| 27 | 26 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 case LIBUSB_ISO_USAGE_TYPE_FEEDBACK: | 81 case LIBUSB_ISO_USAGE_TYPE_FEEDBACK: |
| 83 return USB_USAGE_FEEDBACK; | 82 return USB_USAGE_FEEDBACK; |
| 84 case LIBUSB_ISO_USAGE_TYPE_IMPLICIT: | 83 case LIBUSB_ISO_USAGE_TYPE_IMPLICIT: |
| 85 return USB_USAGE_EXPLICIT_FEEDBACK; | 84 return USB_USAGE_EXPLICIT_FEEDBACK; |
| 86 default: | 85 default: |
| 87 NOTREACHED(); | 86 NOTREACHED(); |
| 88 return USB_USAGE_DATA; | 87 return USB_USAGE_DATA; |
| 89 } | 88 } |
| 90 } | 89 } |
| 91 | 90 |
| 91 void SetConfigDescriptor(const libusb_config_descriptor* platform_config, | |
|
Reilly Grant (use Gerrit)
2015/08/03 18:04:04
I suggest renaming this to "ConvertConfigDescripto
juncai
2015/08/03 21:56:25
Done.
| |
| 92 UsbConfigDescriptor* configuration) { | |
| 93 configuration->configuration_value = platform_config->bConfigurationValue; | |
| 94 configuration->self_powered = (platform_config->bmAttributes & 0x40) != 0; | |
| 95 configuration->remote_wakeup = (platform_config->bmAttributes & 0x20) != 0; | |
| 96 configuration->maximum_power = platform_config->MaxPower * 2; | |
| 97 | |
| 98 for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) { | |
| 99 const struct libusb_interface* platform_interface = | |
| 100 &platform_config->interface[i]; | |
| 101 for (int j = 0; j < platform_interface->num_altsetting; ++j) { | |
| 102 const struct libusb_interface_descriptor* platform_alt_setting = | |
| 103 &platform_interface->altsetting[j]; | |
| 104 UsbInterfaceDescriptor interface; | |
| 105 | |
| 106 interface.interface_number = platform_alt_setting->bInterfaceNumber; | |
| 107 interface.alternate_setting = platform_alt_setting->bAlternateSetting; | |
| 108 interface.interface_class = platform_alt_setting->bInterfaceClass; | |
| 109 interface.interface_subclass = platform_alt_setting->bInterfaceSubClass; | |
| 110 interface.interface_protocol = platform_alt_setting->bInterfaceProtocol; | |
| 111 | |
| 112 for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) { | |
| 113 const struct libusb_endpoint_descriptor* platform_endpoint = | |
| 114 &platform_alt_setting->endpoint[k]; | |
| 115 UsbEndpointDescriptor endpoint; | |
| 116 | |
| 117 endpoint.address = platform_endpoint->bEndpointAddress; | |
| 118 endpoint.direction = GetDirection(platform_endpoint); | |
| 119 endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize; | |
| 120 endpoint.synchronization_type = | |
| 121 GetSynchronizationType(platform_endpoint); | |
| 122 endpoint.transfer_type = GetTransferType(platform_endpoint); | |
| 123 endpoint.usage_type = GetUsageType(platform_endpoint); | |
| 124 endpoint.polling_interval = platform_endpoint->bInterval; | |
| 125 endpoint.extra_data = std::vector<uint8_t>( | |
| 126 platform_endpoint->extra, | |
| 127 platform_endpoint->extra + platform_endpoint->extra_length); | |
| 128 | |
| 129 interface.endpoints.push_back(endpoint); | |
| 130 } | |
| 131 | |
| 132 interface.extra_data = std::vector<uint8_t>( | |
| 133 platform_alt_setting->extra, | |
| 134 platform_alt_setting->extra + platform_alt_setting->extra_length); | |
| 135 | |
| 136 configuration->interfaces.push_back(interface); | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 configuration->extra_data = std::vector<uint8_t>( | |
| 141 platform_config->extra, | |
| 142 platform_config->extra + platform_config->extra_length); | |
| 143 } | |
| 144 | |
| 92 } // namespace | 145 } // namespace |
| 93 | 146 |
| 94 UsbDeviceImpl::UsbDeviceImpl( | 147 UsbDeviceImpl::UsbDeviceImpl( |
| 95 scoped_refptr<UsbContext> context, | 148 scoped_refptr<UsbContext> context, |
| 96 PlatformUsbDevice platform_device, | 149 PlatformUsbDevice platform_device, |
| 97 uint16 vendor_id, | 150 uint16 vendor_id, |
| 98 uint16 product_id, | 151 uint16 product_id, |
| 99 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | 152 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) |
| 100 : UsbDevice(vendor_id, | 153 : UsbDevice(vendor_id, |
| 101 product_id, | 154 product_id, |
| 102 base::string16(), | 155 base::string16(), |
| 103 base::string16(), | 156 base::string16(), |
| 104 base::string16()), | 157 base::string16()), |
| 105 platform_device_(platform_device), | 158 platform_device_(platform_device), |
| 106 context_(context), | 159 context_(context), |
| 107 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 160 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 108 blocking_task_runner_(blocking_task_runner) { | 161 blocking_task_runner_(blocking_task_runner) { |
| 109 CHECK(platform_device) << "platform_device cannot be NULL"; | 162 CHECK(platform_device) << "platform_device cannot be NULL"; |
| 110 libusb_ref_device(platform_device); | 163 libusb_ref_device(platform_device); |
| 164 set_configurations(); | |
|
Reilly Grant (use Gerrit)
2015/08/03 18:04:04
This function is non-trivial and so cannot use thi
juncai
2015/08/03 21:56:25
Done.
| |
| 111 RefreshConfiguration(); | 165 RefreshConfiguration(); |
|
Reilly Grant (use Gerrit)
2015/08/03 18:04:04
I suggest renaming this to "RefreshActiveConfigura
juncai
2015/08/03 21:56:25
Done.
| |
| 112 } | 166 } |
| 113 | 167 |
| 114 UsbDeviceImpl::~UsbDeviceImpl() { | 168 UsbDeviceImpl::~UsbDeviceImpl() { |
| 115 // The destructor must be safe to call from any thread. | 169 // The destructor must be safe to call from any thread. |
| 116 libusb_unref_device(platform_device_); | 170 libusb_unref_device(platform_device_); |
| 117 } | 171 } |
| 118 | 172 |
| 119 #if defined(OS_CHROMEOS) | 173 #if defined(OS_CHROMEOS) |
| 120 | 174 |
| 121 void UsbDeviceImpl::CheckUsbAccess(const ResultCallback& callback) { | 175 void UsbDeviceImpl::CheckUsbAccess(const ResultCallback& callback) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 152 ++it) { | 206 ++it) { |
| 153 if (it->get() == handle.get()) { | 207 if (it->get() == handle.get()) { |
| 154 (*it)->InternalClose(); | 208 (*it)->InternalClose(); |
| 155 handles_.erase(it); | 209 handles_.erase(it); |
| 156 return true; | 210 return true; |
| 157 } | 211 } |
| 158 } | 212 } |
| 159 return false; | 213 return false; |
| 160 } | 214 } |
| 161 | 215 |
| 162 const UsbConfigDescriptor* UsbDeviceImpl::GetConfiguration() { | 216 const UsbConfigDescriptor* UsbDeviceImpl::GetActiveConfiguration() { |
| 163 DCHECK(thread_checker_.CalledOnValidThread()); | 217 DCHECK(thread_checker_.CalledOnValidThread()); |
| 164 return configuration_.get(); | 218 return configuration_; |
| 165 } | 219 } |
| 166 | 220 |
| 167 void UsbDeviceImpl::OnDisconnect() { | 221 void UsbDeviceImpl::OnDisconnect() { |
| 168 DCHECK(thread_checker_.CalledOnValidThread()); | 222 DCHECK(thread_checker_.CalledOnValidThread()); |
| 169 | 223 |
| 170 // Swap the list of handles into a local variable because closing all open | 224 // Swap the list of handles into a local variable because closing all open |
| 171 // handles may release the last reference to this object. | 225 // handles may release the last reference to this object. |
| 172 HandlesVector handles; | 226 HandlesVector handles; |
| 173 swap(handles, handles_); | 227 swap(handles, handles_); |
| 174 | 228 |
| 175 for (const scoped_refptr<UsbDeviceHandleImpl>& handle : handles_) { | 229 for (const scoped_refptr<UsbDeviceHandleImpl>& handle : handles_) { |
| 176 handle->InternalClose(); | 230 handle->InternalClose(); |
| 177 } | 231 } |
| 178 } | 232 } |
| 179 | 233 |
| 234 void UsbDeviceImpl::set_configurations() { | |
| 235 libusb_device_descriptor device_descriptor; | |
| 236 int rv = libusb_get_device_descriptor(platform_device_, &device_descriptor); | |
| 237 if (rv == LIBUSB_SUCCESS) { | |
| 238 uint8_t num_configurations = device_descriptor.bNumConfigurations; | |
| 239 configurations_.reserve(num_configurations); | |
| 240 for (uint8_t i = 0; i < num_configurations; i++) { | |
| 241 libusb_config_descriptor* platform_config; | |
| 242 rv = libusb_get_config_descriptor(platform_device_, i, &platform_config); | |
| 243 if (rv != LIBUSB_SUCCESS) { | |
| 244 USB_LOG(EVENT) << "Failed to get config descriptor: " | |
| 245 << ConvertPlatformUsbErrorToString(rv); | |
| 246 continue; | |
| 247 } | |
| 248 | |
| 249 UsbConfigDescriptor config_descriptor; | |
| 250 SetConfigDescriptor(platform_config, &config_descriptor); | |
| 251 configurations_.push_back(config_descriptor); | |
| 252 libusb_free_config_descriptor(platform_config); | |
| 253 } | |
| 254 } else { | |
| 255 USB_LOG(EVENT) << "Failed to get device descriptor: " | |
| 256 << ConvertPlatformUsbErrorToString(rv); | |
| 257 } | |
| 258 } | |
| 259 | |
| 180 void UsbDeviceImpl::RefreshConfiguration() { | 260 void UsbDeviceImpl::RefreshConfiguration() { |
| 181 libusb_config_descriptor* platform_config; | 261 libusb_config_descriptor* platform_config; |
| 182 int rv = | 262 int rv = |
| 183 libusb_get_active_config_descriptor(platform_device_, &platform_config); | 263 libusb_get_active_config_descriptor(platform_device_, &platform_config); |
| 184 if (rv != LIBUSB_SUCCESS) { | 264 if (rv != LIBUSB_SUCCESS) { |
| 185 USB_LOG(EVENT) << "Failed to get config descriptor: " | 265 USB_LOG(EVENT) << "Failed to get config descriptor: " |
| 186 << ConvertPlatformUsbErrorToString(rv); | 266 << ConvertPlatformUsbErrorToString(rv); |
| 187 return; | 267 return; |
| 188 } | 268 } |
| 189 | 269 |
| 190 configuration_.reset(new UsbConfigDescriptor()); | 270 configuration_ = nullptr; |
| 191 configuration_->configuration_value = platform_config->bConfigurationValue; | 271 size_t num_configurations = configurations_.size(); |
| 192 configuration_->self_powered = (platform_config->bmAttributes & 0x40) != 0; | 272 for (size_t i = 0; i < num_configurations; ++i) { |
| 193 configuration_->remote_wakeup = (platform_config->bmAttributes & 0x20) != 0; | 273 if (configurations_[i].configuration_value == |
| 194 configuration_->maximum_power = platform_config->MaxPower * 2; | 274 platform_config->bConfigurationValue) { |
| 195 | 275 configuration_ = &configurations_[i]; |
| 196 for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) { | 276 break; |
| 197 const struct libusb_interface* platform_interface = | |
| 198 &platform_config->interface[i]; | |
| 199 for (int j = 0; j < platform_interface->num_altsetting; ++j) { | |
| 200 const struct libusb_interface_descriptor* platform_alt_setting = | |
| 201 &platform_interface->altsetting[j]; | |
| 202 UsbInterfaceDescriptor interface; | |
| 203 | |
| 204 interface.interface_number = platform_alt_setting->bInterfaceNumber; | |
| 205 interface.alternate_setting = platform_alt_setting->bAlternateSetting; | |
| 206 interface.interface_class = platform_alt_setting->bInterfaceClass; | |
| 207 interface.interface_subclass = platform_alt_setting->bInterfaceSubClass; | |
| 208 interface.interface_protocol = platform_alt_setting->bInterfaceProtocol; | |
| 209 | |
| 210 for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) { | |
| 211 const struct libusb_endpoint_descriptor* platform_endpoint = | |
| 212 &platform_alt_setting->endpoint[k]; | |
| 213 UsbEndpointDescriptor endpoint; | |
| 214 | |
| 215 endpoint.address = platform_endpoint->bEndpointAddress; | |
| 216 endpoint.direction = GetDirection(platform_endpoint); | |
| 217 endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize; | |
| 218 endpoint.synchronization_type = | |
| 219 GetSynchronizationType(platform_endpoint); | |
| 220 endpoint.transfer_type = GetTransferType(platform_endpoint); | |
| 221 endpoint.usage_type = GetUsageType(platform_endpoint); | |
| 222 endpoint.polling_interval = platform_endpoint->bInterval; | |
| 223 endpoint.extra_data = std::vector<uint8_t>( | |
| 224 platform_endpoint->extra, | |
| 225 platform_endpoint->extra + platform_endpoint->extra_length); | |
| 226 | |
| 227 interface.endpoints.push_back(endpoint); | |
| 228 } | |
| 229 | |
| 230 interface.extra_data = std::vector<uint8_t>( | |
| 231 platform_alt_setting->extra, | |
| 232 platform_alt_setting->extra + platform_alt_setting->extra_length); | |
| 233 | |
| 234 configuration_->interfaces.push_back(interface); | |
| 235 } | 277 } |
| 236 } | 278 } |
| 237 | 279 |
| 238 configuration_->extra_data = std::vector<uint8_t>( | |
| 239 platform_config->extra, | |
| 240 platform_config->extra + platform_config->extra_length); | |
| 241 | |
| 242 libusb_free_config_descriptor(platform_config); | 280 libusb_free_config_descriptor(platform_config); |
| 243 } | 281 } |
| 244 | 282 |
| 245 #if defined(OS_CHROMEOS) | 283 #if defined(OS_CHROMEOS) |
| 246 | 284 |
| 247 void UsbDeviceImpl::OnOpenRequestComplete(const OpenCallback& callback, | 285 void UsbDeviceImpl::OnOpenRequestComplete(const OpenCallback& callback, |
| 248 dbus::FileDescriptor fd) { | 286 dbus::FileDescriptor fd) { |
| 249 blocking_task_runner_->PostTask( | 287 blocking_task_runner_->PostTask( |
| 250 FROM_HERE, base::Bind(&UsbDeviceImpl::OpenOnBlockingThreadWithFd, this, | 288 FROM_HERE, base::Bind(&UsbDeviceImpl::OpenOnBlockingThreadWithFd, this, |
| 251 base::Passed(&fd), callback)); | 289 base::Passed(&fd), callback)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 void UsbDeviceImpl::Opened(PlatformUsbDeviceHandle platform_handle, | 328 void UsbDeviceImpl::Opened(PlatformUsbDeviceHandle platform_handle, |
| 291 const OpenCallback& callback) { | 329 const OpenCallback& callback) { |
| 292 DCHECK(thread_checker_.CalledOnValidThread()); | 330 DCHECK(thread_checker_.CalledOnValidThread()); |
| 293 scoped_refptr<UsbDeviceHandleImpl> device_handle = new UsbDeviceHandleImpl( | 331 scoped_refptr<UsbDeviceHandleImpl> device_handle = new UsbDeviceHandleImpl( |
| 294 context_, this, platform_handle, blocking_task_runner_); | 332 context_, this, platform_handle, blocking_task_runner_); |
| 295 handles_.push_back(device_handle); | 333 handles_.push_back(device_handle); |
| 296 callback.Run(device_handle); | 334 callback.Run(device_handle); |
| 297 } | 335 } |
| 298 | 336 |
| 299 } // namespace device | 337 } // namespace device |
| OLD | NEW |