| Index: chrome/browser/devtools/adb/android_usb_device.cc
|
| diff --git a/chrome/browser/devtools/adb/android_usb_device.cc b/chrome/browser/devtools/adb/android_usb_device.cc
|
| index 17ae407eaeb4647e65b59877d4ad4f06f17cc67e..5d49caceff245efcf0d9f2b40f43c78d8fa1003c 100644
|
| --- a/chrome/browser/devtools/adb/android_usb_device.cc
|
| +++ b/chrome/browser/devtools/adb/android_usb_device.cc
|
| @@ -4,7 +4,10 @@
|
|
|
| #include "chrome/browser/devtools/adb/android_usb_device.h"
|
|
|
| +#include <set>
|
| +
|
| #include "base/base64.h"
|
| +#include "base/lazy_instance.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "chrome/browser/devtools/adb/android_rsa.h"
|
| @@ -12,6 +15,7 @@
|
| #include "chrome/browser/usb/usb_interface.h"
|
| #include "chrome/browser/usb/usb_service.h"
|
| #include "chrome/browser/usb/usb_service_factory.h"
|
| +#include "crypto/rsa_private_key.h"
|
| #include "net/base/ip_endpoint.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/socket/stream_socket.h"
|
| @@ -34,6 +38,11 @@ const uint32 kVersion = 0x01000000;
|
|
|
| static const char kHostConnectMessage[] = "host::";
|
|
|
| +typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
|
| +
|
| +base::LazyInstance<AndroidUsbDevices>::Leaky g_devices =
|
| + LAZY_INSTANCE_INITIALIZER;
|
| +
|
| static std::string ReadSerialNumSync(libusb_device_handle* handle) {
|
| libusb_device* device = libusb_get_device(handle);
|
| libusb_device_descriptor descriptor;
|
| @@ -84,28 +93,28 @@ static std::string ReadSerialNumSync(libusb_device_handle* handle) {
|
| return std::string();
|
| }
|
|
|
| -static void InterfaceClaimed(Profile* profile,
|
| +static void InterfaceClaimed(crypto::RSAPrivateKey* rsa_key,
|
| scoped_refptr<UsbDevice> usb_device,
|
| int inbound_address,
|
| int outbound_address,
|
| int zero_mask,
|
| - AndroidUsbDevice::Devices* devices,
|
| + AndroidUsbDevices* devices,
|
| bool success) {
|
| if (!success)
|
| return;
|
|
|
| std::string serial = ReadSerialNumSync(usb_device->handle());
|
| scoped_refptr<AndroidUsbDevice> device =
|
| - new AndroidUsbDevice(profile, usb_device, serial, inbound_address,
|
| + new AndroidUsbDevice(rsa_key, usb_device, serial, inbound_address,
|
| outbound_address, zero_mask);
|
| devices->push_back(device);
|
| }
|
|
|
| static void ClaimInterface(
|
| - Profile* profile,
|
| + crypto::RSAPrivateKey* rsa_key,
|
| scoped_refptr<UsbDevice> usb_device,
|
| const UsbInterface* interface,
|
| - AndroidUsbDevice::Devices* devices) {
|
| + AndroidUsbDevices* devices) {
|
| if (interface->GetNumAltSettings() == 0)
|
| return;
|
|
|
| @@ -138,10 +147,10 @@ static void ClaimInterface(
|
| if (inbound_address == 0 || outbound_address == 0)
|
| return;
|
|
|
| - usb_device->ClaimInterface(1, base::Bind(&InterfaceClaimed, profile,
|
| - usb_device, inbound_address,
|
| - outbound_address, zero_mask,
|
| - devices));
|
| + usb_device->ClaimInterface(1, base::Bind(&InterfaceClaimed,
|
| + rsa_key, usb_device,
|
| + inbound_address, outbound_address,
|
| + zero_mask, devices));
|
| }
|
|
|
| static uint32 Checksum(const std::string& data) {
|
| @@ -198,32 +207,61 @@ AdbMessage::~AdbMessage() {
|
| }
|
|
|
| // static
|
| -void AndroidUsbDevice::Enumerate(Profile* profile, Devices* devices) {
|
| +void AndroidUsbDevice::Enumerate(Profile* profile,
|
| + crypto::RSAPrivateKey* rsa_key,
|
| + AndroidUsbDevices* devices) {
|
| UsbService* service =
|
| UsbServiceFactory::GetInstance()->GetForProfile(profile);
|
| -
|
| - // Enumerate usb devices.
|
| - std::vector<scoped_refptr<UsbDevice> > usb_devices;
|
| + UsbDevices usb_devices;
|
| service->EnumerateDevices(&usb_devices);
|
| - for (size_t i = 0; i < usb_devices.size(); ++i) {
|
| - scoped_refptr<UsbDevice> usb_device = usb_devices[i];
|
|
|
| - // Enumerate device interfaces.
|
| + // GC Android devices with no actual usb device.
|
| + AndroidUsbDevices::iterator it = g_devices.Get().begin();
|
| + std::set<UsbDevice*> claimed_devices;
|
| + while (it != g_devices.Get().end()) {
|
| + bool found_device = false;
|
| + for (UsbDevices::iterator it2 = usb_devices.begin();
|
| + it2 != usb_devices.end() && !found_device; ++it2) {
|
| + UsbDevice* usb_device = it2->get();
|
| + AndroidUsbDevice* device = it->get();
|
| + if (usb_device == device->usb_device_) {
|
| + found_device = true;
|
| + claimed_devices.insert(*it2);
|
| + }
|
| + }
|
| +
|
| + if (!found_device)
|
| + it = g_devices.Get().erase(it);
|
| + else
|
| + ++it;
|
| + }
|
| +
|
| + // Add new devices.
|
| + AndroidUsbDevices new_devices;
|
| + for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
|
| + ++it) {
|
| + UsbDevice* usb_device = *it;
|
| + if (claimed_devices.find(usb_device) != claimed_devices.end())
|
| + continue;
|
| scoped_refptr<UsbConfigDescriptor> config = new UsbConfigDescriptor();
|
| usb_device->ListInterfaces(config.get(), base::Bind(&BoolNoop));
|
| - for (size_t i = 0; i < config->GetNumInterfaces(); ++i)
|
| - ClaimInterface(profile, usb_device, config->GetInterface(i), devices);
|
| + for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
|
| + ClaimInterface(rsa_key, usb_device, config->GetInterface(j),
|
| + &g_devices.Get());
|
| + }
|
| }
|
| +
|
| + *devices = g_devices.Get();
|
| }
|
|
|
| -AndroidUsbDevice::AndroidUsbDevice(Profile* profile,
|
| +AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
|
| scoped_refptr<UsbDevice> usb_device,
|
| const std::string& serial,
|
| int inbound_address,
|
| int outbound_address,
|
| int zero_mask)
|
| : message_loop_(NULL),
|
| - profile_(profile),
|
| + rsa_key_(rsa_key->Copy()),
|
| usb_device_(usb_device),
|
| serial_(serial),
|
| inbound_address_(inbound_address),
|
| @@ -231,7 +269,8 @@ AndroidUsbDevice::AndroidUsbDevice(Profile* profile,
|
| zero_mask_(zero_mask),
|
| is_connected_(false),
|
| signature_sent_(false),
|
| - last_socket_id_(256) {
|
| + last_socket_id_(256),
|
| + terminated_(false) {
|
| message_loop_ = base::MessageLoop::current();
|
| Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
|
| kHostConnectMessage));
|
| @@ -414,10 +453,10 @@ void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
|
| if (signature_sent_) {
|
| Queue(new AdbMessage(AdbMessage::kCommandAUTH,
|
| AdbMessage::kAuthRSAPublicKey, 0,
|
| - AndroidRSAPublicKey(profile_)));
|
| + AndroidRSAPublicKey(rsa_key_.get())));
|
| } else {
|
| signature_sent_ = true;
|
| - std::string signature = AndroidRSASign(profile_, message->body);
|
| + std::string signature = AndroidRSASign(rsa_key_.get(), message->body);
|
| if (!signature.empty()) {
|
| Queue(new AdbMessage(AdbMessage::kCommandAUTH,
|
| AdbMessage::kAuthSignature, 0,
|
| @@ -425,7 +464,7 @@ void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
|
| } else {
|
| Queue(new AdbMessage(AdbMessage::kCommandAUTH,
|
| AdbMessage::kAuthRSAPublicKey, 0,
|
| - AndroidRSAPublicKey(profile_)));
|
| + AndroidRSAPublicKey(rsa_key_.get())));
|
| }
|
| }
|
| }
|
| @@ -457,17 +496,24 @@ void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
|
| }
|
|
|
| void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
|
| - LOG(ERROR) << "Transfer error " << status;
|
| message_loop_->PostTask(FROM_HERE,
|
| base::Bind(&AndroidUsbDevice::Terminate,
|
| this));
|
| }
|
|
|
| void AndroidUsbDevice::Terminate() {
|
| - for (AndroidUsbSockets::iterator it = sockets_.begin();
|
| - it != sockets_.end(); ++it) {
|
| + if (terminated_)
|
| + return;
|
| +
|
| + terminated_ = true;
|
| +
|
| + // Iterate over copy.
|
| + AndroidUsbSockets sockets(sockets_);
|
| + for (AndroidUsbSockets::iterator it = sockets.begin();
|
| + it != sockets.end(); ++it) {
|
| it->second->Terminated();
|
| }
|
| +
|
| usb_device_->ReleaseInterface(1, base::Bind(&BoolNoop));
|
| usb_device_->Close(base::Bind(&Noop));
|
| }
|
|
|