Chromium Code Reviews| 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); |
| 204 | |
| 205 // Enumerate usb devices. | |
| 206 std::vector<scoped_refptr<UsbDevice> > usb_devices; | 215 std::vector<scoped_refptr<UsbDevice> > usb_devices; |
|
vsevik
2013/07/11 15:59:54
UsbDevices
pfeldman
2013/07/11 16:26:51
Done.
| |
| 207 service->EnumerateDevices(&usb_devices); | 216 service->EnumerateDevices(&usb_devices); |
| 208 for (size_t i = 0; i < usb_devices.size(); ++i) { | |
| 209 scoped_refptr<UsbDevice> usb_device = usb_devices[i]; | |
| 210 | 217 |
| 211 // Enumerate device interfaces. | 218 // GC Android devices with no actual usb device. |
| 219 AndroidUsbDevices::iterator it = g_devices.Get().begin(); | |
| 220 std::set<UsbDevice*> claimed_devices; | |
| 221 while (it != g_devices.Get().end()) { | |
| 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 } | |
| 232 | |
| 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 18 matching lines...) Expand all Loading... | |
| 457 } | 496 } |
| 458 | 497 |
| 459 void AndroidUsbDevice::TransferError(UsbTransferStatus status) { | 498 void AndroidUsbDevice::TransferError(UsbTransferStatus status) { |
| 460 LOG(ERROR) << "Transfer error " << status; | 499 LOG(ERROR) << "Transfer error " << status; |
| 461 message_loop_->PostTask(FROM_HERE, | 500 message_loop_->PostTask(FROM_HERE, |
| 462 base::Bind(&AndroidUsbDevice::Terminate, | 501 base::Bind(&AndroidUsbDevice::Terminate, |
| 463 this)); | 502 this)); |
| 464 } | 503 } |
| 465 | 504 |
| 466 void AndroidUsbDevice::Terminate() { | 505 void AndroidUsbDevice::Terminate() { |
| 506 if (terminated_) | |
| 507 return; | |
| 508 | |
| 509 terminated_ = true; | |
| 467 for (AndroidUsbSockets::iterator it = sockets_.begin(); | 510 for (AndroidUsbSockets::iterator it = sockets_.begin(); |
| 468 it != sockets_.end(); ++it) { | 511 it != sockets_.end(); ++it) { |
| 469 it->second->Terminated(); | 512 it->second->Terminated(); |
| 470 } | 513 } |
| 514 | |
| 471 usb_device_->ReleaseInterface(1, base::Bind(&BoolNoop)); | 515 usb_device_->ReleaseInterface(1, base::Bind(&BoolNoop)); |
| 472 usb_device_->Close(base::Bind(&Noop)); | 516 usb_device_->Close(base::Bind(&Noop)); |
| 473 } | 517 } |
| 474 | 518 |
| 475 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { | 519 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { |
| 476 sockets_.erase(socket_id); | 520 sockets_.erase(socket_id); |
| 477 } | 521 } |
| OLD | NEW |