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 "chrome/browser/devtools/adb/android_rsa.h"
17 #include "chrome/browser/devtools/adb/android_usb_socket.h"
18 #include "chrome/browser/usb/usb_device.h"
19 #include "chrome/browser/usb/usb_interface.h"
20 #include "chrome/browser/usb/usb_service.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "crypto/rsa_private_key.h"
23 #include "net/base/ip_endpoint.h"
24 #include "net/base/net_errors.h"
25 #include "net/socket/stream_socket.h"
29 const size_t kHeaderSize = 24;
31 const int kAdbClass = 0xff;
32 const int kAdbSubclass = 0x42;
33 const int kAdbProtocol = 0x1;
35 const int kUsbTimeout = 0;
37 const uint32 kMaxPayload = 4096;
38 const uint32 kVersion = 0x01000000;
40 static const char kHostConnectMessage[] = "host::";
42 using content::BrowserThread;
44 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
45 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet;
47 base::LazyInstance<AndroidUsbDevices>::Leaky g_devices =
48 LAZY_INSTANCE_INITIALIZER;
50 bool IsAndroidInterface(
51 scoped_refptr<const UsbInterfaceDescriptor> interface) {
52 if (interface->GetNumAltSettings() == 0)
55 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc =
56 interface->GetAltSetting(0);
58 if (idesc->GetInterfaceClass() != kAdbClass ||
59 idesc->GetInterfaceSubclass() != kAdbSubclass ||
60 idesc->GetInterfaceProtocol() != kAdbProtocol ||
61 idesc->GetNumEndpoints() != 2) {
67 scoped_refptr<AndroidUsbDevice> ClaimInterface(
68 crypto::RSAPrivateKey* rsa_key,
69 scoped_refptr<UsbDeviceHandle> usb_handle,
70 scoped_refptr<const UsbInterfaceDescriptor> interface,
72 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc =
73 interface->GetAltSetting(0);
75 int inbound_address = 0;
76 int outbound_address = 0;
79 for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) {
80 scoped_refptr<const UsbEndpointDescriptor> edesc =
81 idesc->GetEndpoint(i);
82 if (edesc->GetTransferType() != USB_TRANSFER_BULK)
84 if (edesc->GetDirection() == USB_DIRECTION_INBOUND)
85 inbound_address = edesc->GetAddress();
87 outbound_address = edesc->GetAddress();
88 zero_mask = edesc->GetMaximumPacketSize() - 1;
91 if (inbound_address == 0 || outbound_address == 0)
94 if (!usb_handle->ClaimInterface(interface_id))
97 base::string16 serial;
98 if (!usb_handle->GetSerial(&serial) || serial.empty())
101 return new AndroidUsbDevice(rsa_key, usb_handle, UTF16ToASCII(serial),
102 inbound_address, outbound_address, zero_mask);
105 uint32 Checksum(const std::string& data) {
106 unsigned char* x = (unsigned char*)data.data();
107 int count = data.length();
114 void DumpMessage(bool outgoing, const char* data, size_t length) {
116 std::string result = "";
117 if (length == kHeaderSize) {
118 for (size_t i = 0; i < 24; ++i) {
119 result += base::StringPrintf("%02x",
120 data[i] > 0 ? data[i] : (data[i] + 0x100) & 0xFF);
121 if ((i + 1) % 4 == 0)
124 for (size_t i = 0; i < 24; ++i) {
125 if (data[i] >= 0x20 && data[i] <= 0x7E)
131 result = base::StringPrintf("%d: ", (int)length);
132 for (size_t i = 0; i < length; ++i) {
133 if (data[i] >= 0x20 && data[i] <= 0x7E)
139 LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result;
143 void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device) {
144 usb_device->ReleaseInterface(1);
150 AdbMessage::AdbMessage(uint32 command,
153 const std::string& body)
160 AdbMessage::~AdbMessage() {
163 static void RespondWithCountOnUIThread(base::Callback<void(int)> callback,
165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
169 static void RespondOnUIThread(const AndroidUsbDevicesCallback& callback,
170 const AndroidUsbDevices& devices) {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
172 callback.Run(devices);
175 static void RespondOnFileThread(const AndroidUsbDevicesCallback& callback) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
177 // Copy g_devices.Get() on file thread.
178 BrowserThread::PostTask(
179 BrowserThread::UI, FROM_HERE,
180 base::Bind(&RespondOnUIThread, callback, g_devices.Get()));
183 static void OpenAndroidDevicesOnFileThread(
184 crypto::RSAPrivateKey* rsa_key,
185 const base::Closure& barrier,
186 scoped_refptr<UsbDevice> device,
189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
191 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces();
192 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open();
194 scoped_refptr<AndroidUsbDevice> device =
195 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id),
198 g_devices.Get().push_back(device);
206 static void CountOnFileThread(
207 const base::Callback<void(int)>& callback) {
208 UsbService* service = UsbService::GetInstance();
209 UsbDevices usb_devices;
210 service->GetDevices(&usb_devices);
211 int device_count = 0;
212 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
214 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces();
218 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
219 if (IsAndroidInterface(config->GetInterface(j)))
223 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
224 base::Bind(&RespondWithCountOnUIThread, callback,
228 static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key,
229 const AndroidUsbDevicesCallback& callback) {
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
232 UsbService* service = UsbService::GetInstance();
233 UsbDevices usb_devices;
234 service->GetDevices(&usb_devices);
236 AndroidUsbDevices& devices = g_devices.Get();
238 // GC Android devices with no actual usb device.
239 AndroidUsbDevices::iterator it = devices.begin();
240 UsbDeviceSet claimed_devices;
241 while (it != devices.end()) {
242 bool found_device = false;
243 for (UsbDevices::iterator it2 = usb_devices.begin();
244 it2 != usb_devices.end() && !found_device; ++it2) {
245 UsbDevice* usb_device = it2->get();
246 AndroidUsbDevice* device = it->get();
247 if (usb_device == device->usb_device()->device()) {
249 claimed_devices.insert(usb_device);
254 it = devices.erase(it);
260 base::Closure barrier = base::BarrierClosure(
261 usb_devices.size(), base::Bind(&RespondOnFileThread, callback));
263 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
265 if (ContainsKey(claimed_devices, it->get())) {
270 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces();
276 bool has_android_interface = false;
277 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
278 if (!IsAndroidInterface(config->GetInterface(j)))
281 // Request permission on Chrome OS.
282 #if defined(OS_CHROMEOS)
283 (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDevicesOnFileThread,
284 rsa_key, barrier, *it, j));
286 OpenAndroidDevicesOnFileThread(rsa_key, barrier, *it, j, true);
287 #endif // defined(OS_CHROMEOS)
289 has_android_interface = true;
292 if (!has_android_interface)
298 void AndroidUsbDevice::CountDevices(
299 const base::Callback<void(int)>& callback) {
300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
301 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
302 base::Bind(&CountOnFileThread, callback));
306 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key,
307 const AndroidUsbDevicesCallback& callback) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
309 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
310 base::Bind(&EnumerateOnFileThread, rsa_key,
314 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
315 scoped_refptr<UsbDeviceHandle> usb_device,
316 const std::string& serial,
318 int outbound_address,
320 : message_loop_(NULL),
321 rsa_key_(rsa_key->Copy()),
322 usb_device_(usb_device),
324 inbound_address_(inbound_address),
325 outbound_address_(outbound_address),
326 zero_mask_(zero_mask),
327 is_connected_(false),
328 signature_sent_(false),
329 last_socket_id_(256),
333 void AndroidUsbDevice::InitOnCallerThread() {
336 message_loop_ = base::MessageLoop::current();
337 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
338 kHostConnectMessage));
342 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) {
343 uint32 socket_id = ++last_socket_id_;
344 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command,
345 base::Bind(&AndroidUsbDevice::SocketDeleted, this));
346 return sockets_[socket_id];
349 void AndroidUsbDevice::Send(uint32 command,
352 const std::string& body) {
353 scoped_refptr<AdbMessage> m = new AdbMessage(command, arg0, arg1, body);
354 // Delay open request if not yet connected.
355 if (!is_connected_) {
356 pending_messages_.push_back(m);
362 AndroidUsbDevice::~AndroidUsbDevice() {
364 usb_device_->AddRef();
365 BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE,
369 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
371 std::vector<uint32> header;
372 header.push_back(message->command);
373 header.push_back(message->arg0);
374 header.push_back(message->arg1);
375 bool append_zero = true;
376 if (message->body.empty())
378 if (message->command == AdbMessage::kCommandAUTH &&
379 message->arg0 == AdbMessage::kAuthSignature)
381 if (message->command == AdbMessage::kCommandWRTE)
384 size_t body_length = message->body.length() + (append_zero ? 1 : 0);
385 header.push_back(body_length);
386 header.push_back(Checksum(message->body));
387 header.push_back(message->command ^ 0xffffffff);
388 scoped_refptr<net::IOBuffer> header_buffer = new net::IOBuffer(kHeaderSize);
389 memcpy(header_buffer.get()->data(), &header[0], kHeaderSize);
390 outgoing_queue_.push(std::make_pair(header_buffer, kHeaderSize));
393 if (!message->body.empty()) {
394 scoped_refptr<net::IOBuffer> body_buffer = new net::IOBuffer(body_length);
395 memcpy(body_buffer->data(), message->body.data(), message->body.length());
397 body_buffer->data()[body_length - 1] = 0;
398 outgoing_queue_.push(std::make_pair(body_buffer, body_length));
399 if (zero_mask_ && (body_length & zero_mask_) == 0) {
400 // Send a zero length packet.
401 outgoing_queue_.push(std::make_pair(body_buffer, 0));
407 void AndroidUsbDevice::ProcessOutgoing() {
408 if (outgoing_queue_.empty() || terminated_)
411 BulkMessage message = outgoing_queue_.front();
412 outgoing_queue_.pop();
413 DumpMessage(true, message.first->data(), message.second);
414 usb_device_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_,
415 message.first, message.second, kUsbTimeout,
416 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, this));
419 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status,
420 scoped_refptr<net::IOBuffer> buffer,
422 if (status != USB_TRANSFER_COMPLETED)
424 message_loop_->PostTask(FROM_HERE,
425 base::Bind(&AndroidUsbDevice::ProcessOutgoing,
429 void AndroidUsbDevice::ReadHeader(bool initial) {
432 if (!initial && HasOneRef())
433 return; // Stop polling.
434 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize);
435 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
436 buffer, kHeaderSize, kUsbTimeout,
437 base::Bind(&AndroidUsbDevice::ParseHeader, this));
440 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
441 scoped_refptr<net::IOBuffer> buffer,
443 if (status == USB_TRANSFER_TIMEOUT) {
444 message_loop_->PostTask(FROM_HERE,
445 base::Bind(&AndroidUsbDevice::ReadHeader, this,
450 if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) {
451 TransferError(status);
455 DumpMessage(false, buffer->data(), result);
456 std::vector<uint32> header(6);
457 memcpy(&header[0], buffer->data(), result);
458 scoped_refptr<AdbMessage> message =
459 new AdbMessage(header[0], header[1], header[2], "");
460 uint32 data_length = header[3];
461 uint32 data_check = header[4];
462 uint32 magic = header[5];
463 if ((message->command ^ 0xffffffff) != magic) {
464 TransferError(USB_TRANSFER_ERROR);
468 if (data_length == 0) {
469 message_loop_->PostTask(FROM_HERE,
470 base::Bind(&AndroidUsbDevice::HandleIncoming, this,
475 message_loop_->PostTask(FROM_HERE,
476 base::Bind(&AndroidUsbDevice::ReadBody, this,
477 message, data_length, data_check));
480 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message,
483 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length);
484 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
485 buffer, data_length, kUsbTimeout,
486 base::Bind(&AndroidUsbDevice::ParseBody, this, message, data_length,
490 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message,
493 UsbTransferStatus status,
494 scoped_refptr<net::IOBuffer> buffer,
496 if (status == USB_TRANSFER_TIMEOUT) {
497 message_loop_->PostTask(FROM_HERE,
498 base::Bind(&AndroidUsbDevice::ReadBody, this,
499 message, data_length, data_check));
503 if (status != USB_TRANSFER_COMPLETED ||
504 static_cast<uint32>(result) != data_length) {
505 TransferError(status);
509 DumpMessage(false, buffer->data(), data_length);
510 message->body = std::string(buffer->data(), result);
511 if (Checksum(message->body) != data_check) {
512 TransferError(USB_TRANSFER_ERROR);
516 message_loop_->PostTask(FROM_HERE,
517 base::Bind(&AndroidUsbDevice::HandleIncoming, this,
521 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
522 switch (message->command) {
523 case AdbMessage::kCommandAUTH:
525 DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken));
526 if (signature_sent_) {
527 Queue(new AdbMessage(AdbMessage::kCommandAUTH,
528 AdbMessage::kAuthRSAPublicKey, 0,
529 AndroidRSAPublicKey(rsa_key_.get())));
531 signature_sent_ = true;
532 std::string signature = AndroidRSASign(rsa_key_.get(), message->body);
533 if (!signature.empty()) {
534 Queue(new AdbMessage(AdbMessage::kCommandAUTH,
535 AdbMessage::kAuthSignature, 0,
538 Queue(new AdbMessage(AdbMessage::kCommandAUTH,
539 AdbMessage::kAuthRSAPublicKey, 0,
540 AndroidRSAPublicKey(rsa_key_.get())));
545 case AdbMessage::kCommandCNXN:
547 is_connected_ = true;
548 PendingMessages pending;
549 pending.swap(pending_messages_);
550 for (PendingMessages::iterator it = pending.begin();
551 it != pending.end(); ++it) {
556 case AdbMessage::kCommandOKAY:
557 case AdbMessage::kCommandWRTE:
558 case AdbMessage::kCommandCLSE:
560 AndroidUsbSockets::iterator it = sockets_.find(message->arg1);
561 if (it != sockets_.end())
562 it->second->HandleIncoming(message);
571 void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
572 message_loop_->PostTask(FROM_HERE,
573 base::Bind(&AndroidUsbDevice::Terminate,
577 void AndroidUsbDevice::Terminate() {
583 // Iterate over copy.
584 AndroidUsbSockets sockets(sockets_);
585 for (AndroidUsbSockets::iterator it = sockets.begin();
586 it != sockets.end(); ++it) {
587 it->second->Terminated();
590 BrowserThread::PostTask(
591 BrowserThread::FILE, FROM_HERE,
592 base::Bind(&ReleaseInterface, usb_device_));
595 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
596 sockets_.erase(socket_id);