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
3 // found in the LICENSE file.
5 #include "chrome/browser/devtools/adb/android_usb_device.h"
9 #include "base/barrier_closure.h"
10 #include "base/base64.h"
11 #include "base/lazy_instance.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/stl_util.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/browser/devtools/adb/android_rsa.h"
18 #include "chrome/browser/devtools/adb/android_usb_socket.h"
19 #include "chrome/browser/usb/usb_device.h"
20 #include "chrome/browser/usb/usb_interface.h"
21 #include "chrome/browser/usb/usb_service.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "crypto/rsa_private_key.h"
24 #include "net/base/ip_endpoint.h"
25 #include "net/base/net_errors.h"
26 #include "net/socket/stream_socket.h"
30 const size_t kHeaderSize = 24;
32 const int kAdbClass = 0xff;
33 const int kAdbSubclass = 0x42;
34 const int kAdbProtocol = 0x1;
36 const int kUsbTimeout = 0;
38 const uint32 kMaxPayload = 4096;
39 const uint32 kVersion = 0x01000000;
41 static const char kHostConnectMessage[] = "host::";
43 using content::BrowserThread;
45 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
46 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet;
48 base::LazyInstance<AndroidUsbDevices>::Leaky g_devices =
49 LAZY_INSTANCE_INITIALIZER;
51 bool IsAndroidInterface(
52 scoped_refptr<const UsbInterfaceDescriptor> interface) {
53 if (interface->GetNumAltSettings() == 0)
56 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc =
57 interface->GetAltSetting(0);
59 if (idesc->GetInterfaceClass() != kAdbClass ||
60 idesc->GetInterfaceSubclass() != kAdbSubclass ||
61 idesc->GetInterfaceProtocol() != kAdbProtocol ||
62 idesc->GetNumEndpoints() != 2) {
68 scoped_refptr<AndroidUsbDevice> ClaimInterface(
69 crypto::RSAPrivateKey* rsa_key,
70 scoped_refptr<UsbDeviceHandle> usb_handle,
71 scoped_refptr<const UsbInterfaceDescriptor> interface,
73 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc =
74 interface->GetAltSetting(0);
76 int inbound_address = 0;
77 int outbound_address = 0;
80 for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) {
81 scoped_refptr<const UsbEndpointDescriptor> edesc =
82 idesc->GetEndpoint(i);
83 if (edesc->GetTransferType() != USB_TRANSFER_BULK)
85 if (edesc->GetDirection() == USB_DIRECTION_INBOUND)
86 inbound_address = edesc->GetAddress();
88 outbound_address = edesc->GetAddress();
89 zero_mask = edesc->GetMaximumPacketSize() - 1;
92 if (inbound_address == 0 || outbound_address == 0)
95 if (!usb_handle->ClaimInterface(interface_id))
98 base::string16 serial;
99 if (!usb_handle->GetSerial(&serial) || serial.empty())
102 return new AndroidUsbDevice(rsa_key, usb_handle, base::UTF16ToASCII(serial),
103 inbound_address, outbound_address, zero_mask);
106 uint32 Checksum(const std::string& data) {
107 unsigned char* x = (unsigned char*)data.data();
108 int count = data.length();
115 void DumpMessage(bool outgoing, const char* data, size_t length) {
117 std::string result = "";
118 if (length == kHeaderSize) {
119 for (size_t i = 0; i < 24; ++i) {
120 result += base::StringPrintf("%02x",
121 data[i] > 0 ? data[i] : (data[i] + 0x100) & 0xFF);
122 if ((i + 1) % 4 == 0)
125 for (size_t i = 0; i < 24; ++i) {
126 if (data[i] >= 0x20 && data[i] <= 0x7E)
132 result = base::StringPrintf("%d: ", (int)length);
133 for (size_t i = 0; i < length; ++i) {
134 if (data[i] >= 0x20 && data[i] <= 0x7E)
140 LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result;
144 void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device) {
145 usb_device->ReleaseInterface(1);
151 AdbMessage::AdbMessage(uint32 command,
154 const std::string& body)
161 AdbMessage::~AdbMessage() {
164 static void RespondWithCountOnUIThread(base::Callback<void(int)> callback,
166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
170 static void RespondOnUIThread(const AndroidUsbDevicesCallback& callback,
171 const AndroidUsbDevices& devices) {
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
173 callback.Run(devices);
176 static void RespondOnFileThread(const AndroidUsbDevicesCallback& callback) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
178 // Copy g_devices.Get() on file thread.
179 BrowserThread::PostTask(
180 BrowserThread::UI, FROM_HERE,
181 base::Bind(&RespondOnUIThread, callback, g_devices.Get()));
184 static void OpenAndroidDevicesOnFileThread(
185 crypto::RSAPrivateKey* rsa_key,
186 const base::Closure& barrier,
187 scoped_refptr<UsbDevice> device,
190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
192 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces();
193 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open();
195 scoped_refptr<AndroidUsbDevice> device =
196 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id),
199 g_devices.Get().push_back(device);
207 static void CountOnFileThread(
208 const base::Callback<void(int)>& callback) {
209 UsbService* service = UsbService::GetInstance();
210 UsbDevices usb_devices;
212 service->GetDevices(&usb_devices);
213 int device_count = 0;
214 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
216 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces();
220 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
221 if (IsAndroidInterface(config->GetInterface(j)))
225 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
226 base::Bind(&RespondWithCountOnUIThread, callback,
230 static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key,
231 const AndroidUsbDevicesCallback& callback) {
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
234 UsbService* service = UsbService::GetInstance();
235 UsbDevices usb_devices;
237 service->GetDevices(&usb_devices);
239 AndroidUsbDevices& devices = g_devices.Get();
241 // GC Android devices with no actual usb device.
242 AndroidUsbDevices::iterator it = devices.begin();
243 UsbDeviceSet claimed_devices;
244 while (it != devices.end()) {
245 bool found_device = false;
246 for (UsbDevices::iterator it2 = usb_devices.begin();
247 it2 != usb_devices.end() && !found_device; ++it2) {
248 UsbDevice* usb_device = it2->get();
249 AndroidUsbDevice* device = it->get();
250 if (usb_device == device->usb_device()->device()) {
252 claimed_devices.insert(usb_device);
257 it = devices.erase(it);
263 base::Closure barrier = base::BarrierClosure(
264 usb_devices.size(), base::Bind(&RespondOnFileThread, callback));
266 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
268 if (ContainsKey(claimed_devices, it->get())) {
273 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces();
279 bool has_android_interface = false;
280 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
281 if (!IsAndroidInterface(config->GetInterface(j)))
284 // Request permission on Chrome OS.
285 #if defined(OS_CHROMEOS)
286 (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDevicesOnFileThread,
287 rsa_key, barrier, *it, j));
289 OpenAndroidDevicesOnFileThread(rsa_key, barrier, *it, j, true);
290 #endif // defined(OS_CHROMEOS)
292 has_android_interface = true;
295 if (!has_android_interface)
301 void AndroidUsbDevice::CountDevices(
302 const base::Callback<void(int)>& callback) {
303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
304 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
305 base::Bind(&CountOnFileThread, callback));
309 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key,
310 const AndroidUsbDevicesCallback& callback) {
311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
312 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
313 base::Bind(&EnumerateOnFileThread, rsa_key,
317 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
318 scoped_refptr<UsbDeviceHandle> usb_device,
319 const std::string& serial,
321 int outbound_address,
323 : message_loop_(NULL),
324 rsa_key_(rsa_key->Copy()),
325 usb_device_(usb_device),
327 inbound_address_(inbound_address),
328 outbound_address_(outbound_address),
329 zero_mask_(zero_mask),
330 is_connected_(false),
331 signature_sent_(false),
332 last_socket_id_(256),
336 void AndroidUsbDevice::InitOnCallerThread() {
339 message_loop_ = base::MessageLoop::current();
340 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
341 kHostConnectMessage));
345 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) {
346 uint32 socket_id = ++last_socket_id_;
347 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command,
348 base::Bind(&AndroidUsbDevice::SocketDeleted, this));
349 return sockets_[socket_id];
352 void AndroidUsbDevice::Send(uint32 command,
355 const std::string& body) {
356 scoped_refptr<AdbMessage> m = new AdbMessage(command, arg0, arg1, body);
357 // Delay open request if not yet connected.
358 if (!is_connected_) {
359 pending_messages_.push_back(m);
365 AndroidUsbDevice::~AndroidUsbDevice() {
367 usb_device_->AddRef();
368 BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE,
372 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
374 std::vector<uint32> header;
375 header.push_back(message->command);
376 header.push_back(message->arg0);
377 header.push_back(message->arg1);
378 bool append_zero = true;
379 if (message->body.empty())
381 if (message->command == AdbMessage::kCommandAUTH &&
382 message->arg0 == AdbMessage::kAuthSignature)
384 if (message->command == AdbMessage::kCommandWRTE)
387 size_t body_length = message->body.length() + (append_zero ? 1 : 0);
388 header.push_back(body_length);
389 header.push_back(Checksum(message->body));
390 header.push_back(message->command ^ 0xffffffff);
391 scoped_refptr<net::IOBuffer> header_buffer = new net::IOBuffer(kHeaderSize);
392 memcpy(header_buffer.get()->data(), &header[0], kHeaderSize);
393 outgoing_queue_.push(std::make_pair(header_buffer, kHeaderSize));
396 if (!message->body.empty()) {
397 scoped_refptr<net::IOBuffer> body_buffer = new net::IOBuffer(body_length);
398 memcpy(body_buffer->data(), message->body.data(), message->body.length());
400 body_buffer->data()[body_length - 1] = 0;
401 outgoing_queue_.push(std::make_pair(body_buffer, body_length));
402 if (zero_mask_ && (body_length & zero_mask_) == 0) {
403 // Send a zero length packet.
404 outgoing_queue_.push(std::make_pair(body_buffer, 0));
410 void AndroidUsbDevice::ProcessOutgoing() {
411 if (outgoing_queue_.empty() || terminated_)
414 BulkMessage message = outgoing_queue_.front();
415 outgoing_queue_.pop();
416 DumpMessage(true, message.first->data(), message.second);
417 usb_device_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_,
418 message.first, message.second, kUsbTimeout,
419 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, this));
422 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status,
423 scoped_refptr<net::IOBuffer> buffer,
425 if (status != USB_TRANSFER_COMPLETED)
427 message_loop_->PostTask(FROM_HERE,
428 base::Bind(&AndroidUsbDevice::ProcessOutgoing,
432 void AndroidUsbDevice::ReadHeader(bool initial) {
435 if (!initial && HasOneRef())
436 return; // Stop polling.
437 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize);
438 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
439 buffer, kHeaderSize, kUsbTimeout,
440 base::Bind(&AndroidUsbDevice::ParseHeader, this));
443 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
444 scoped_refptr<net::IOBuffer> buffer,
446 if (status == USB_TRANSFER_TIMEOUT) {
447 message_loop_->PostTask(FROM_HERE,
448 base::Bind(&AndroidUsbDevice::ReadHeader, this,
453 if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) {
454 TransferError(status);
458 DumpMessage(false, buffer->data(), result);
459 std::vector<uint32> header(6);
460 memcpy(&header[0], buffer->data(), result);
461 scoped_refptr<AdbMessage> message =
462 new AdbMessage(header[0], header[1], header[2], "");
463 uint32 data_length = header[3];
464 uint32 data_check = header[4];
465 uint32 magic = header[5];
466 if ((message->command ^ 0xffffffff) != magic) {
467 TransferError(USB_TRANSFER_ERROR);
471 if (data_length == 0) {
472 message_loop_->PostTask(FROM_HERE,
473 base::Bind(&AndroidUsbDevice::HandleIncoming, this,
478 message_loop_->PostTask(FROM_HERE,
479 base::Bind(&AndroidUsbDevice::ReadBody, this,
480 message, data_length, data_check));
483 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message,
486 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length);
487 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
488 buffer, data_length, kUsbTimeout,
489 base::Bind(&AndroidUsbDevice::ParseBody, this, message, data_length,
493 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message,
496 UsbTransferStatus status,
497 scoped_refptr<net::IOBuffer> buffer,
499 if (status == USB_TRANSFER_TIMEOUT) {
500 message_loop_->PostTask(FROM_HERE,
501 base::Bind(&AndroidUsbDevice::ReadBody, this,
502 message, data_length, data_check));
506 if (status != USB_TRANSFER_COMPLETED ||
507 static_cast<uint32>(result) != data_length) {
508 TransferError(status);
512 DumpMessage(false, buffer->data(), data_length);
513 message->body = std::string(buffer->data(), result);
514 if (Checksum(message->body) != data_check) {
515 TransferError(USB_TRANSFER_ERROR);
519 message_loop_->PostTask(FROM_HERE,
520 base::Bind(&AndroidUsbDevice::HandleIncoming, this,
524 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
525 switch (message->command) {
526 case AdbMessage::kCommandAUTH:
528 DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken));
529 if (signature_sent_) {
530 Queue(new AdbMessage(AdbMessage::kCommandAUTH,
531 AdbMessage::kAuthRSAPublicKey, 0,
532 AndroidRSAPublicKey(rsa_key_.get())));
534 signature_sent_ = true;
535 std::string signature = AndroidRSASign(rsa_key_.get(), message->body);
536 if (!signature.empty()) {
537 Queue(new AdbMessage(AdbMessage::kCommandAUTH,
538 AdbMessage::kAuthSignature, 0,
541 Queue(new AdbMessage(AdbMessage::kCommandAUTH,
542 AdbMessage::kAuthRSAPublicKey, 0,
543 AndroidRSAPublicKey(rsa_key_.get())));
548 case AdbMessage::kCommandCNXN:
550 is_connected_ = true;
551 PendingMessages pending;
552 pending.swap(pending_messages_);
553 for (PendingMessages::iterator it = pending.begin();
554 it != pending.end(); ++it) {
559 case AdbMessage::kCommandOKAY:
560 case AdbMessage::kCommandWRTE:
561 case AdbMessage::kCommandCLSE:
563 AndroidUsbSockets::iterator it = sockets_.find(message->arg1);
564 if (it != sockets_.end())
565 it->second->HandleIncoming(message);
574 void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
575 message_loop_->PostTask(FROM_HERE,
576 base::Bind(&AndroidUsbDevice::Terminate,
580 void AndroidUsbDevice::Terminate() {
586 // Iterate over copy.
587 AndroidUsbSockets sockets(sockets_);
588 for (AndroidUsbSockets::iterator it = sockets.begin();
589 it != sockets.end(); ++it) {
590 it->second->Terminated();
593 BrowserThread::PostTask(
594 BrowserThread::FILE, FROM_HERE,
595 base::Bind(&ReleaseInterface, usb_device_));
598 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
599 sockets_.erase(socket_id);