| 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 "chrome/browser/devtools/device/usb/android_usb_device.h" | 5 #include "chrome/browser/devtools/device/usb/android_usb_device.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/barrier_closure.h" | 9 #include "base/barrier_closure.h" |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 17 #include "chrome/browser/devtools/device/usb/android_rsa.h" | 17 #include "chrome/browser/devtools/device/usb/android_rsa.h" |
| 18 #include "chrome/browser/devtools/device/usb/android_usb_socket.h" | 18 #include "chrome/browser/devtools/device/usb/android_usb_socket.h" |
| 19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 20 #include "crypto/rsa_private_key.h" | 20 #include "crypto/rsa_private_key.h" |
| 21 #include "device/core/device_client.h" | 21 #include "device/core/device_client.h" |
| 22 #include "device/usb/usb_descriptors.h" |
| 22 #include "device/usb/usb_device.h" | 23 #include "device/usb/usb_device.h" |
| 23 #include "device/usb/usb_interface.h" | |
| 24 #include "device/usb/usb_service.h" | 24 #include "device/usb/usb_service.h" |
| 25 #include "net/base/ip_endpoint.h" | 25 #include "net/base/ip_endpoint.h" |
| 26 #include "net/base/net_errors.h" | 26 #include "net/base/net_errors.h" |
| 27 #include "net/socket/stream_socket.h" | 27 #include "net/socket/stream_socket.h" |
| 28 | 28 |
| 29 using device::UsbConfigDescriptor; | 29 using device::UsbConfigDescriptor; |
| 30 using device::UsbDevice; | 30 using device::UsbDevice; |
| 31 using device::UsbDeviceHandle; | 31 using device::UsbDeviceHandle; |
| 32 using device::UsbInterfaceAltSettingDescriptor; | |
| 33 using device::UsbInterfaceDescriptor; | 32 using device::UsbInterfaceDescriptor; |
| 34 using device::UsbEndpointDescriptor; | 33 using device::UsbEndpointDescriptor; |
| 35 using device::UsbService; | 34 using device::UsbService; |
| 36 using device::UsbTransferStatus; | 35 using device::UsbTransferStatus; |
| 37 | 36 |
| 38 namespace { | 37 namespace { |
| 39 | 38 |
| 40 const size_t kHeaderSize = 24; | 39 const size_t kHeaderSize = 24; |
| 41 | 40 |
| 42 const int kAdbClass = 0xff; | 41 const int kAdbClass = 0xff; |
| 43 const int kAdbSubclass = 0x42; | 42 const int kAdbSubclass = 0x42; |
| 44 const int kAdbProtocol = 0x1; | 43 const int kAdbProtocol = 0x1; |
| 45 | 44 |
| 46 const int kUsbTimeout = 0; | 45 const int kUsbTimeout = 0; |
| 47 | 46 |
| 48 const uint32 kMaxPayload = 4096; | 47 const uint32 kMaxPayload = 4096; |
| 49 const uint32 kVersion = 0x01000000; | 48 const uint32 kVersion = 0x01000000; |
| 50 | 49 |
| 51 static const char kHostConnectMessage[] = "host::"; | 50 static const char kHostConnectMessage[] = "host::"; |
| 52 | 51 |
| 53 using content::BrowserThread; | 52 using content::BrowserThread; |
| 54 | 53 |
| 55 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices; | 54 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices; |
| 56 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet; | 55 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet; |
| 57 | 56 |
| 58 // Stores android wrappers around claimed usb devices on caller thread. | 57 // Stores android wrappers around claimed usb devices on caller thread. |
| 59 base::LazyInstance<std::vector<AndroidUsbDevice*> >::Leaky g_devices = | 58 base::LazyInstance<std::vector<AndroidUsbDevice*> >::Leaky g_devices = |
| 60 LAZY_INSTANCE_INITIALIZER; | 59 LAZY_INSTANCE_INITIALIZER; |
| 61 | 60 |
| 62 bool IsAndroidInterface(scoped_refptr<const UsbInterfaceDescriptor> interface) { | 61 bool IsAndroidInterface(const UsbInterfaceDescriptor& interface) { |
| 63 if (interface->GetNumAltSettings() == 0) | 62 if (interface.alternate_setting != 0 || |
| 64 return false; | 63 interface.interface_class != kAdbClass || |
| 65 | 64 interface.interface_subclass != kAdbSubclass || |
| 66 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = | 65 interface.interface_protocol != kAdbProtocol || |
| 67 interface->GetAltSetting(0); | 66 interface.endpoints.size() != 2) { |
| 68 | |
| 69 if (idesc->GetInterfaceClass() != kAdbClass || | |
| 70 idesc->GetInterfaceSubclass() != kAdbSubclass || | |
| 71 idesc->GetInterfaceProtocol() != kAdbProtocol || | |
| 72 idesc->GetNumEndpoints() != 2) { | |
| 73 return false; | 67 return false; |
| 74 } | 68 } |
| 75 return true; | 69 return true; |
| 76 } | 70 } |
| 77 | 71 |
| 78 scoped_refptr<AndroidUsbDevice> ClaimInterface( | 72 scoped_refptr<AndroidUsbDevice> ClaimInterface( |
| 79 crypto::RSAPrivateKey* rsa_key, | 73 crypto::RSAPrivateKey* rsa_key, |
| 80 scoped_refptr<UsbDeviceHandle> usb_handle, | 74 scoped_refptr<UsbDeviceHandle> usb_handle, |
| 81 scoped_refptr<const UsbInterfaceDescriptor> interface, | 75 const UsbInterfaceDescriptor& interface) { |
| 82 int interface_id) { | |
| 83 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc = | |
| 84 interface->GetAltSetting(0); | |
| 85 | |
| 86 int inbound_address = 0; | 76 int inbound_address = 0; |
| 87 int outbound_address = 0; | 77 int outbound_address = 0; |
| 88 int zero_mask = 0; | 78 int zero_mask = 0; |
| 89 | 79 |
| 90 for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) { | 80 for (UsbEndpointDescriptor::Iterator endpointIt = interface.endpoints.begin(); |
| 91 scoped_refptr<const UsbEndpointDescriptor> edesc = | 81 endpointIt != interface.endpoints.end(); |
| 92 idesc->GetEndpoint(i); | 82 ++endpointIt) { |
| 93 if (edesc->GetTransferType() != device::USB_TRANSFER_BULK) | 83 if (endpointIt->transfer_type != device::USB_TRANSFER_BULK) |
| 94 continue; | 84 continue; |
| 95 if (edesc->GetDirection() == device::USB_DIRECTION_INBOUND) | 85 if (endpointIt->direction == device::USB_DIRECTION_INBOUND) |
| 96 inbound_address = edesc->GetAddress(); | 86 inbound_address = endpointIt->address; |
| 97 else | 87 else |
| 98 outbound_address = edesc->GetAddress(); | 88 outbound_address = endpointIt->address; |
| 99 zero_mask = edesc->GetMaximumPacketSize() - 1; | 89 zero_mask = endpointIt->maximum_packet_size - 1; |
| 100 } | 90 } |
| 101 | 91 |
| 102 if (inbound_address == 0 || outbound_address == 0) | 92 if (inbound_address == 0 || outbound_address == 0) |
| 103 return NULL; | 93 return NULL; |
| 104 | 94 |
| 105 if (!usb_handle->ClaimInterface(interface_id)) | 95 if (!usb_handle->ClaimInterface(interface.interface_number)) |
| 106 return NULL; | 96 return NULL; |
| 107 | 97 |
| 108 base::string16 serial; | 98 base::string16 serial; |
| 109 if (!usb_handle->GetSerial(&serial) || serial.empty()) | 99 if (!usb_handle->GetSerial(&serial) || serial.empty()) |
| 110 return NULL; | 100 return NULL; |
| 111 | 101 |
| 112 return new AndroidUsbDevice(rsa_key, usb_handle, base::UTF16ToASCII(serial), | 102 return new AndroidUsbDevice(rsa_key, |
| 113 inbound_address, outbound_address, zero_mask, | 103 usb_handle, |
| 114 interface_id); | 104 base::UTF16ToASCII(serial), |
| 105 inbound_address, |
| 106 outbound_address, |
| 107 zero_mask, |
| 108 interface.interface_number); |
| 115 } | 109 } |
| 116 | 110 |
| 117 uint32 Checksum(const std::string& data) { | 111 uint32 Checksum(const std::string& data) { |
| 118 unsigned char* x = (unsigned char*)data.data(); | 112 unsigned char* x = (unsigned char*)data.data(); |
| 119 int count = data.length(); | 113 int count = data.length(); |
| 120 uint32 sum = 0; | 114 uint32 sum = 0; |
| 121 while (count-- > 0) | 115 while (count-- > 0) |
| 122 sum += *x++; | 116 sum += *x++; |
| 123 return sum; | 117 return sum; |
| 124 } | 118 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 | 194 |
| 201 static void OpenAndroidDeviceOnFileThread( | 195 static void OpenAndroidDeviceOnFileThread( |
| 202 AndroidUsbDevices* devices, | 196 AndroidUsbDevices* devices, |
| 203 crypto::RSAPrivateKey* rsa_key, | 197 crypto::RSAPrivateKey* rsa_key, |
| 204 const base::Closure& barrier, | 198 const base::Closure& barrier, |
| 205 scoped_refptr<UsbDevice> device, | 199 scoped_refptr<UsbDevice> device, |
| 206 int interface_id, | 200 int interface_id, |
| 207 bool success) { | 201 bool success) { |
| 208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 209 if (success) { | 203 if (success) { |
| 210 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces(); | 204 const UsbConfigDescriptor& config = device->GetConfiguration(); |
| 211 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open(); | 205 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open(); |
| 212 if (usb_handle.get()) { | 206 if (usb_handle.get()) { |
| 213 scoped_refptr<AndroidUsbDevice> android_device = | 207 scoped_refptr<AndroidUsbDevice> android_device = |
| 214 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id), | 208 ClaimInterface(rsa_key, usb_handle, config.interfaces[interface_id]); |
| 215 interface_id); | |
| 216 if (android_device.get()) | 209 if (android_device.get()) |
| 217 devices->push_back(android_device.get()); | 210 devices->push_back(android_device.get()); |
| 218 else | 211 else |
| 219 usb_handle->Close(); | 212 usb_handle->Close(); |
| 220 } | 213 } |
| 221 } | 214 } |
| 222 barrier.Run(); | 215 barrier.Run(); |
| 223 } | 216 } |
| 224 | 217 |
| 225 static int CountOnFileThread() { | 218 static int CountOnFileThread() { |
| 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 227 UsbService* service = device::DeviceClient::Get()->GetUsbService(); | 220 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
| 228 UsbDevices usb_devices; | 221 UsbDevices usb_devices; |
| 229 if (service != NULL) | 222 if (service != NULL) |
| 230 service->GetDevices(&usb_devices); | 223 service->GetDevices(&usb_devices); |
| 231 int device_count = 0; | 224 int device_count = 0; |
| 232 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); | 225 for (UsbDevices::iterator deviceIt = usb_devices.begin(); |
| 233 ++it) { | 226 deviceIt != usb_devices.end(); |
| 234 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); | 227 ++deviceIt) { |
| 235 if (!config.get()) | 228 const UsbConfigDescriptor& config = (*deviceIt)->GetConfiguration(); |
| 236 continue; | |
| 237 | 229 |
| 238 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { | 230 for (UsbInterfaceDescriptor::Iterator ifaceIt = config.interfaces.begin(); |
| 239 if (IsAndroidInterface(config->GetInterface(j))) | 231 ifaceIt != config.interfaces.end(); |
| 232 ++ifaceIt) { |
| 233 if (IsAndroidInterface(*ifaceIt)) { |
| 240 ++device_count; | 234 ++device_count; |
| 235 } |
| 241 } | 236 } |
| 242 } | 237 } |
| 243 return device_count; | 238 return device_count; |
| 244 } | 239 } |
| 245 | 240 |
| 246 static void EnumerateOnFileThread( | 241 static void EnumerateOnFileThread( |
| 247 crypto::RSAPrivateKey* rsa_key, | 242 crypto::RSAPrivateKey* rsa_key, |
| 248 const AndroidUsbDevicesCallback& callback, | 243 const AndroidUsbDevicesCallback& callback, |
| 249 scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) { | 244 scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) { |
| 250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 251 | 246 |
| 252 UsbService* service = device::DeviceClient::Get()->GetUsbService(); | 247 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
| 253 UsbDevices usb_devices; | 248 UsbDevices usb_devices; |
| 254 if (service != NULL) | 249 if (service != NULL) |
| 255 service->GetDevices(&usb_devices); | 250 service->GetDevices(&usb_devices); |
| 256 | 251 |
| 257 // Add new devices. | 252 // Add new devices. |
| 258 AndroidUsbDevices* devices = new AndroidUsbDevices(); | 253 AndroidUsbDevices* devices = new AndroidUsbDevices(); |
| 259 base::Closure barrier = base::BarrierClosure( | 254 base::Closure barrier = base::BarrierClosure( |
| 260 usb_devices.size(), base::Bind(&RespondOnFileThread, | 255 usb_devices.size(), base::Bind(&RespondOnFileThread, |
| 261 callback, | 256 callback, |
| 262 devices, | 257 devices, |
| 263 caller_message_loop_proxy)); | 258 caller_message_loop_proxy)); |
| 264 | 259 |
| 265 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); | 260 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); |
| 266 ++it) { | 261 ++it) { |
| 267 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); | 262 const UsbConfigDescriptor& config = (*it)->GetConfiguration(); |
| 268 if (!config.get()) { | |
| 269 barrier.Run(); | |
| 270 continue; | |
| 271 } | |
| 272 | 263 |
| 273 bool has_android_interface = false; | 264 bool has_android_interface = false; |
| 274 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { | 265 for (size_t j = 0; j < config.interfaces.size(); ++j) { |
| 275 if (!IsAndroidInterface(config->GetInterface(j))) | 266 if (!IsAndroidInterface(config.interfaces[j])) { |
| 276 continue; | 267 continue; |
| 268 } |
| 277 | 269 |
| 278 // Request permission on Chrome OS. | 270 // Request permission on Chrome OS. |
| 279 #if defined(OS_CHROMEOS) | 271 #if defined(OS_CHROMEOS) |
| 280 (*it)->RequestUsbAccess(j, base::Bind(&OpenAndroidDeviceOnFileThread, | 272 (*it)->RequestUsbAccess(j, base::Bind(&OpenAndroidDeviceOnFileThread, |
| 281 devices, rsa_key, barrier, *it, j)); | 273 devices, rsa_key, barrier, *it, j)); |
| 282 #else | 274 #else |
| 283 OpenAndroidDeviceOnFileThread(devices, rsa_key, barrier, *it, j, true); | 275 OpenAndroidDeviceOnFileThread(devices, rsa_key, barrier, *it, j, true); |
| 284 #endif // defined(OS_CHROMEOS) | 276 #endif // defined(OS_CHROMEOS) |
| 285 | 277 |
| 286 has_android_interface = true; | 278 has_android_interface = true; |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 BrowserThread::PostTask( | 646 BrowserThread::PostTask( |
| 655 BrowserThread::FILE, FROM_HERE, | 647 BrowserThread::FILE, FROM_HERE, |
| 656 base::Bind(&ReleaseInterface, usb_handle, interface_id_)); | 648 base::Bind(&ReleaseInterface, usb_handle, interface_id_)); |
| 657 } | 649 } |
| 658 | 650 |
| 659 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { | 651 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { |
| 660 DCHECK(message_loop_ == base::MessageLoop::current()); | 652 DCHECK(message_loop_ == base::MessageLoop::current()); |
| 661 | 653 |
| 662 sockets_.erase(socket_id); | 654 sockets_.erase(socket_id); |
| 663 } | 655 } |
| OLD | NEW |