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