OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/adb/android_usb_device.h" | 5 #include "chrome/browser/devtools/adb/android_usb_device.h" |
6 | 6 |
| 7 #include <set> |
| 8 |
7 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/lazy_instance.h" |
8 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
9 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
10 #include "chrome/browser/devtools/adb/android_rsa.h" | 13 #include "chrome/browser/devtools/adb/android_rsa.h" |
11 #include "chrome/browser/devtools/adb/android_usb_socket.h" | 14 #include "chrome/browser/devtools/adb/android_usb_socket.h" |
12 #include "chrome/browser/usb/usb_interface.h" | 15 #include "chrome/browser/usb/usb_interface.h" |
13 #include "chrome/browser/usb/usb_service.h" | 16 #include "chrome/browser/usb/usb_service.h" |
14 #include "chrome/browser/usb/usb_service_factory.h" | 17 #include "chrome/browser/usb/usb_service_factory.h" |
| 18 #include "crypto/rsa_private_key.h" |
15 #include "net/base/ip_endpoint.h" | 19 #include "net/base/ip_endpoint.h" |
16 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
17 #include "net/socket/stream_socket.h" | 21 #include "net/socket/stream_socket.h" |
18 | 22 |
19 namespace { | 23 namespace { |
20 | 24 |
21 void Noop() {} | 25 void Noop() {} |
22 void BoolNoop(bool success) {} | 26 void BoolNoop(bool success) {} |
23 | 27 |
24 const size_t kHeaderSize = 24; | 28 const size_t kHeaderSize = 24; |
25 | 29 |
26 const int kAdbClass = 0xff; | 30 const int kAdbClass = 0xff; |
27 const int kAdbSubclass = 0x42; | 31 const int kAdbSubclass = 0x42; |
28 const int kAdbProtocol = 0x1; | 32 const int kAdbProtocol = 0x1; |
29 | 33 |
30 const int kUsbTimeout = 1000; | 34 const int kUsbTimeout = 1000; |
31 | 35 |
32 const uint32 kMaxPayload = 4096; | 36 const uint32 kMaxPayload = 4096; |
33 const uint32 kVersion = 0x01000000; | 37 const uint32 kVersion = 0x01000000; |
34 | 38 |
35 static const char kHostConnectMessage[] = "host::"; | 39 static const char kHostConnectMessage[] = "host::"; |
36 | 40 |
| 41 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices; |
| 42 |
| 43 base::LazyInstance<AndroidUsbDevices>::Leaky g_devices = |
| 44 LAZY_INSTANCE_INITIALIZER; |
| 45 |
37 static std::string ReadSerialNumSync(libusb_device_handle* handle) { | 46 static std::string ReadSerialNumSync(libusb_device_handle* handle) { |
38 libusb_device* device = libusb_get_device(handle); | 47 libusb_device* device = libusb_get_device(handle); |
39 libusb_device_descriptor descriptor; | 48 libusb_device_descriptor descriptor; |
40 if (libusb_get_device_descriptor(device, &descriptor) != LIBUSB_SUCCESS) | 49 if (libusb_get_device_descriptor(device, &descriptor) != LIBUSB_SUCCESS) |
41 return std::string(); | 50 return std::string(); |
42 | 51 |
43 if (!descriptor.iSerialNumber) | 52 if (!descriptor.iSerialNumber) |
44 return std::string(); | 53 return std::string(); |
45 | 54 |
46 uint16 languages[128] = {0}; | 55 uint16 languages[128] = {0}; |
(...skipping 30 matching lines...) Expand all Loading... |
77 int j; | 86 int j; |
78 for (j = 1; j < res; ++j) | 87 for (j = 1; j < res; ++j) |
79 serial[j - 1] = buffer[j]; | 88 serial[j - 1] = buffer[j]; |
80 serial[j - 1] = '\0'; | 89 serial[j - 1] = '\0'; |
81 return std::string(serial, j); | 90 return std::string(serial, j); |
82 } | 91 } |
83 } | 92 } |
84 return std::string(); | 93 return std::string(); |
85 } | 94 } |
86 | 95 |
87 static void InterfaceClaimed(Profile* profile, | 96 static void InterfaceClaimed(crypto::RSAPrivateKey* rsa_key, |
88 scoped_refptr<UsbDevice> usb_device, | 97 scoped_refptr<UsbDevice> usb_device, |
89 int inbound_address, | 98 int inbound_address, |
90 int outbound_address, | 99 int outbound_address, |
91 int zero_mask, | 100 int zero_mask, |
92 AndroidUsbDevice::Devices* devices, | 101 AndroidUsbDevices* devices, |
93 bool success) { | 102 bool success) { |
94 if (!success) | 103 if (!success) |
95 return; | 104 return; |
96 | 105 |
97 std::string serial = ReadSerialNumSync(usb_device->handle()); | 106 std::string serial = ReadSerialNumSync(usb_device->handle()); |
98 scoped_refptr<AndroidUsbDevice> device = | 107 scoped_refptr<AndroidUsbDevice> device = |
99 new AndroidUsbDevice(profile, usb_device, serial, inbound_address, | 108 new AndroidUsbDevice(rsa_key, usb_device, serial, inbound_address, |
100 outbound_address, zero_mask); | 109 outbound_address, zero_mask); |
101 devices->push_back(device); | 110 devices->push_back(device); |
102 } | 111 } |
103 | 112 |
104 static void ClaimInterface( | 113 static void ClaimInterface( |
105 Profile* profile, | 114 crypto::RSAPrivateKey* rsa_key, |
106 scoped_refptr<UsbDevice> usb_device, | 115 scoped_refptr<UsbDevice> usb_device, |
107 const UsbInterface* interface, | 116 const UsbInterface* interface, |
108 AndroidUsbDevice::Devices* devices) { | 117 AndroidUsbDevices* devices) { |
109 if (interface->GetNumAltSettings() == 0) | 118 if (interface->GetNumAltSettings() == 0) |
110 return; | 119 return; |
111 | 120 |
112 scoped_refptr<const UsbInterfaceDescriptor> idesc = | 121 scoped_refptr<const UsbInterfaceDescriptor> idesc = |
113 interface->GetAltSetting(0).get(); | 122 interface->GetAltSetting(0).get(); |
114 | 123 |
115 if (idesc->GetInterfaceClass() != kAdbClass || | 124 if (idesc->GetInterfaceClass() != kAdbClass || |
116 idesc->GetInterfaceSubclass() != kAdbSubclass || | 125 idesc->GetInterfaceSubclass() != kAdbSubclass || |
117 idesc->GetInterfaceProtocol() != kAdbProtocol || | 126 idesc->GetInterfaceProtocol() != kAdbProtocol || |
118 idesc->GetNumEndpoints() != 2) { | 127 idesc->GetNumEndpoints() != 2) { |
(...skipping 12 matching lines...) Expand all Loading... |
131 if (edesc->GetDirection() == USB_DIRECTION_INBOUND) | 140 if (edesc->GetDirection() == USB_DIRECTION_INBOUND) |
132 inbound_address = edesc->GetAddress(); | 141 inbound_address = edesc->GetAddress(); |
133 else | 142 else |
134 outbound_address = edesc->GetAddress(); | 143 outbound_address = edesc->GetAddress(); |
135 zero_mask = edesc->GetMaximumPacketSize() - 1; | 144 zero_mask = edesc->GetMaximumPacketSize() - 1; |
136 } | 145 } |
137 | 146 |
138 if (inbound_address == 0 || outbound_address == 0) | 147 if (inbound_address == 0 || outbound_address == 0) |
139 return; | 148 return; |
140 | 149 |
141 usb_device->ClaimInterface(1, base::Bind(&InterfaceClaimed, profile, | 150 usb_device->ClaimInterface(1, base::Bind(&InterfaceClaimed, |
142 usb_device, inbound_address, | 151 rsa_key, usb_device, |
143 outbound_address, zero_mask, | 152 inbound_address, outbound_address, |
144 devices)); | 153 zero_mask, devices)); |
145 } | 154 } |
146 | 155 |
147 static uint32 Checksum(const std::string& data) { | 156 static uint32 Checksum(const std::string& data) { |
148 unsigned char* x = (unsigned char*)data.data(); | 157 unsigned char* x = (unsigned char*)data.data(); |
149 int count = data.length(); | 158 int count = data.length(); |
150 uint32 sum = 0; | 159 uint32 sum = 0; |
151 while (count-- > 0) | 160 while (count-- > 0) |
152 sum += *x++; | 161 sum += *x++; |
153 return sum; | 162 return sum; |
154 } | 163 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 : command(command), | 200 : command(command), |
192 arg0(arg0), | 201 arg0(arg0), |
193 arg1(arg1), | 202 arg1(arg1), |
194 body(body) { | 203 body(body) { |
195 } | 204 } |
196 | 205 |
197 AdbMessage::~AdbMessage() { | 206 AdbMessage::~AdbMessage() { |
198 } | 207 } |
199 | 208 |
200 // static | 209 // static |
201 void AndroidUsbDevice::Enumerate(Profile* profile, Devices* devices) { | 210 void AndroidUsbDevice::Enumerate(Profile* profile, |
| 211 crypto::RSAPrivateKey* rsa_key, |
| 212 AndroidUsbDevices* devices) { |
202 UsbService* service = | 213 UsbService* service = |
203 UsbServiceFactory::GetInstance()->GetForProfile(profile); | 214 UsbServiceFactory::GetInstance()->GetForProfile(profile); |
| 215 UsbDevices usb_devices; |
| 216 service->EnumerateDevices(&usb_devices); |
204 | 217 |
205 // Enumerate usb devices. | 218 // GC Android devices with no actual usb device. |
206 std::vector<scoped_refptr<UsbDevice> > usb_devices; | 219 AndroidUsbDevices::iterator it = g_devices.Get().begin(); |
207 service->EnumerateDevices(&usb_devices); | 220 std::set<UsbDevice*> claimed_devices; |
208 for (size_t i = 0; i < usb_devices.size(); ++i) { | 221 while (it != g_devices.Get().end()) { |
209 scoped_refptr<UsbDevice> usb_device = usb_devices[i]; | 222 bool found_device = false; |
| 223 for (UsbDevices::iterator it2 = usb_devices.begin(); |
| 224 it2 != usb_devices.end() && !found_device; ++it2) { |
| 225 UsbDevice* usb_device = it2->get(); |
| 226 AndroidUsbDevice* device = it->get(); |
| 227 if (usb_device == device->usb_device_) { |
| 228 found_device = true; |
| 229 claimed_devices.insert(*it2); |
| 230 } |
| 231 } |
210 | 232 |
211 // Enumerate device interfaces. | 233 if (!found_device) |
| 234 it = g_devices.Get().erase(it); |
| 235 else |
| 236 ++it; |
| 237 } |
| 238 |
| 239 // Add new devices. |
| 240 AndroidUsbDevices new_devices; |
| 241 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); |
| 242 ++it) { |
| 243 UsbDevice* usb_device = *it; |
| 244 if (claimed_devices.find(usb_device) != claimed_devices.end()) |
| 245 continue; |
212 scoped_refptr<UsbConfigDescriptor> config = new UsbConfigDescriptor(); | 246 scoped_refptr<UsbConfigDescriptor> config = new UsbConfigDescriptor(); |
213 usb_device->ListInterfaces(config.get(), base::Bind(&BoolNoop)); | 247 usb_device->ListInterfaces(config.get(), base::Bind(&BoolNoop)); |
214 for (size_t i = 0; i < config->GetNumInterfaces(); ++i) | 248 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { |
215 ClaimInterface(profile, usb_device, config->GetInterface(i), devices); | 249 ClaimInterface(rsa_key, usb_device, config->GetInterface(j), |
| 250 &g_devices.Get()); |
| 251 } |
216 } | 252 } |
| 253 |
| 254 *devices = g_devices.Get(); |
217 } | 255 } |
218 | 256 |
219 AndroidUsbDevice::AndroidUsbDevice(Profile* profile, | 257 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key, |
220 scoped_refptr<UsbDevice> usb_device, | 258 scoped_refptr<UsbDevice> usb_device, |
221 const std::string& serial, | 259 const std::string& serial, |
222 int inbound_address, | 260 int inbound_address, |
223 int outbound_address, | 261 int outbound_address, |
224 int zero_mask) | 262 int zero_mask) |
225 : message_loop_(NULL), | 263 : message_loop_(NULL), |
226 profile_(profile), | 264 rsa_key_(rsa_key->Copy()), |
227 usb_device_(usb_device), | 265 usb_device_(usb_device), |
228 serial_(serial), | 266 serial_(serial), |
229 inbound_address_(inbound_address), | 267 inbound_address_(inbound_address), |
230 outbound_address_(outbound_address), | 268 outbound_address_(outbound_address), |
231 zero_mask_(zero_mask), | 269 zero_mask_(zero_mask), |
232 is_connected_(false), | 270 is_connected_(false), |
233 signature_sent_(false), | 271 signature_sent_(false), |
234 last_socket_id_(256) { | 272 last_socket_id_(256), |
| 273 terminated_(false) { |
235 message_loop_ = base::MessageLoop::current(); | 274 message_loop_ = base::MessageLoop::current(); |
236 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload, | 275 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload, |
237 kHostConnectMessage)); | 276 kHostConnectMessage)); |
238 ReadHeader(true); | 277 ReadHeader(true); |
239 } | 278 } |
240 | 279 |
241 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) { | 280 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) { |
242 uint32 socket_id = ++last_socket_id_; | 281 uint32 socket_id = ++last_socket_id_; |
243 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command, | 282 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command, |
244 base::Bind(&AndroidUsbDevice::SocketDeleted, this)); | 283 base::Bind(&AndroidUsbDevice::SocketDeleted, this)); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 } | 446 } |
408 | 447 |
409 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) { | 448 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) { |
410 switch (message->command) { | 449 switch (message->command) { |
411 case AdbMessage::kCommandAUTH: | 450 case AdbMessage::kCommandAUTH: |
412 { | 451 { |
413 DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken)); | 452 DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken)); |
414 if (signature_sent_) { | 453 if (signature_sent_) { |
415 Queue(new AdbMessage(AdbMessage::kCommandAUTH, | 454 Queue(new AdbMessage(AdbMessage::kCommandAUTH, |
416 AdbMessage::kAuthRSAPublicKey, 0, | 455 AdbMessage::kAuthRSAPublicKey, 0, |
417 AndroidRSAPublicKey(profile_))); | 456 AndroidRSAPublicKey(rsa_key_.get()))); |
418 } else { | 457 } else { |
419 signature_sent_ = true; | 458 signature_sent_ = true; |
420 std::string signature = AndroidRSASign(profile_, message->body); | 459 std::string signature = AndroidRSASign(rsa_key_.get(), message->body); |
421 if (!signature.empty()) { | 460 if (!signature.empty()) { |
422 Queue(new AdbMessage(AdbMessage::kCommandAUTH, | 461 Queue(new AdbMessage(AdbMessage::kCommandAUTH, |
423 AdbMessage::kAuthSignature, 0, | 462 AdbMessage::kAuthSignature, 0, |
424 signature)); | 463 signature)); |
425 } else { | 464 } else { |
426 Queue(new AdbMessage(AdbMessage::kCommandAUTH, | 465 Queue(new AdbMessage(AdbMessage::kCommandAUTH, |
427 AdbMessage::kAuthRSAPublicKey, 0, | 466 AdbMessage::kAuthRSAPublicKey, 0, |
428 AndroidRSAPublicKey(profile_))); | 467 AndroidRSAPublicKey(rsa_key_.get()))); |
429 } | 468 } |
430 } | 469 } |
431 } | 470 } |
432 break; | 471 break; |
433 case AdbMessage::kCommandCNXN: | 472 case AdbMessage::kCommandCNXN: |
434 { | 473 { |
435 is_connected_ = true; | 474 is_connected_ = true; |
436 PendingMessages pending; | 475 PendingMessages pending; |
437 pending.swap(pending_messages_); | 476 pending.swap(pending_messages_); |
438 for (PendingMessages::iterator it = pending.begin(); | 477 for (PendingMessages::iterator it = pending.begin(); |
(...skipping 11 matching lines...) Expand all Loading... |
450 it->second->HandleIncoming(message); | 489 it->second->HandleIncoming(message); |
451 } | 490 } |
452 break; | 491 break; |
453 default: | 492 default: |
454 break; | 493 break; |
455 } | 494 } |
456 ReadHeader(false); | 495 ReadHeader(false); |
457 } | 496 } |
458 | 497 |
459 void AndroidUsbDevice::TransferError(UsbTransferStatus status) { | 498 void AndroidUsbDevice::TransferError(UsbTransferStatus status) { |
460 LOG(ERROR) << "Transfer error " << status; | |
461 message_loop_->PostTask(FROM_HERE, | 499 message_loop_->PostTask(FROM_HERE, |
462 base::Bind(&AndroidUsbDevice::Terminate, | 500 base::Bind(&AndroidUsbDevice::Terminate, |
463 this)); | 501 this)); |
464 } | 502 } |
465 | 503 |
466 void AndroidUsbDevice::Terminate() { | 504 void AndroidUsbDevice::Terminate() { |
467 for (AndroidUsbSockets::iterator it = sockets_.begin(); | 505 if (terminated_) |
468 it != sockets_.end(); ++it) { | 506 return; |
| 507 |
| 508 terminated_ = true; |
| 509 |
| 510 // Iterate over copy. |
| 511 AndroidUsbSockets sockets(sockets_); |
| 512 for (AndroidUsbSockets::iterator it = sockets.begin(); |
| 513 it != sockets.end(); ++it) { |
469 it->second->Terminated(); | 514 it->second->Terminated(); |
470 } | 515 } |
| 516 |
471 usb_device_->ReleaseInterface(1, base::Bind(&BoolNoop)); | 517 usb_device_->ReleaseInterface(1, base::Bind(&BoolNoop)); |
472 usb_device_->Close(base::Bind(&Noop)); | 518 usb_device_->Close(base::Bind(&Noop)); |
473 } | 519 } |
474 | 520 |
475 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { | 521 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { |
476 sockets_.erase(socket_id); | 522 sockets_.erase(socket_id); |
477 } | 523 } |
OLD | NEW |