1 // Copyright 2014 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/device/usb/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/device/usb/android_rsa.h"
18 #include "chrome/browser/devtools/device/usb/android_usb_socket.h"
19 #include "components/usb_service/usb_device.h"
20 #include "components/usb_service/usb_interface.h"
21 #include "components/usb_service/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"
28 using usb_service::UsbConfigDescriptor
;
29 using usb_service::UsbDevice
;
30 using usb_service::UsbDeviceHandle
;
31 using usb_service::UsbInterfaceAltSettingDescriptor
;
32 using usb_service::UsbInterfaceDescriptor
;
33 using usb_service::UsbEndpointDescriptor
;
34 using usb_service::UsbService
;
35 using usb_service::UsbTransferStatus
;
39 const size_t kHeaderSize
= 24;
41 const int kAdbClass
= 0xff;
42 const int kAdbSubclass
= 0x42;
43 const int kAdbProtocol
= 0x1;
45 const int kUsbTimeout
= 0;
47 const uint32 kMaxPayload
= 4096;
48 const uint32 kVersion
= 0x01000000;
50 static const char kHostConnectMessage
[] = "host::";
52 using content::BrowserThread
;
54 typedef std::vector
<scoped_refptr
<UsbDevice
> > UsbDevices
;
55 typedef std::set
<scoped_refptr
<UsbDevice
> > UsbDeviceSet
;
57 // Stores android wrappers around claimed usb devices on caller thread.
58 base::LazyInstance
<std::vector
<AndroidUsbDevice
*> >::Leaky g_devices
=
59 LAZY_INSTANCE_INITIALIZER
;
61 bool IsAndroidInterface(
62 scoped_refptr
<const usb_service::UsbInterfaceDescriptor
> interface
) {
63 if (interface
->GetNumAltSettings() == 0)
66 scoped_refptr
<const UsbInterfaceAltSettingDescriptor
> idesc
=
67 interface
->GetAltSetting(0);
69 if (idesc
->GetInterfaceClass() != kAdbClass
||
70 idesc
->GetInterfaceSubclass() != kAdbSubclass
||
71 idesc
->GetInterfaceProtocol() != kAdbProtocol
||
72 idesc
->GetNumEndpoints() != 2) {
78 scoped_refptr
<AndroidUsbDevice
> ClaimInterface(
79 crypto::RSAPrivateKey
* rsa_key
,
80 scoped_refptr
<UsbDeviceHandle
> usb_handle
,
81 scoped_refptr
<const UsbInterfaceDescriptor
> interface
,
83 scoped_refptr
<const UsbInterfaceAltSettingDescriptor
> idesc
=
84 interface
->GetAltSetting(0);
86 int inbound_address
= 0;
87 int outbound_address
= 0;
90 for (size_t i
= 0; i
< idesc
->GetNumEndpoints(); ++i
) {
91 scoped_refptr
<const UsbEndpointDescriptor
> edesc
=
92 idesc
->GetEndpoint(i
);
93 if (edesc
->GetTransferType() != usb_service::USB_TRANSFER_BULK
)
95 if (edesc
->GetDirection() == usb_service::USB_DIRECTION_INBOUND
)
96 inbound_address
= edesc
->GetAddress();
98 outbound_address
= edesc
->GetAddress();
99 zero_mask
= edesc
->GetMaximumPacketSize() - 1;
102 if (inbound_address
== 0 || outbound_address
== 0)
105 if (!usb_handle
->ClaimInterface(interface_id
))
108 base::string16 serial
;
109 if (!usb_handle
->GetSerial(&serial
) || serial
.empty())
112 return new AndroidUsbDevice(rsa_key
, usb_handle
, base::UTF16ToASCII(serial
),
113 inbound_address
, outbound_address
, zero_mask
,
117 uint32
Checksum(const std::string
& data
) {
118 unsigned char* x
= (unsigned char*)data
.data();
119 int count
= data
.length();
126 void DumpMessage(bool outgoing
, const char* data
, size_t length
) {
128 std::string result
= "";
129 if (length
== kHeaderSize
) {
130 for (size_t i
= 0; i
< 24; ++i
) {
131 result
+= base::StringPrintf("%02x",
132 data
[i
] > 0 ? data
[i
] : (data
[i
] + 0x100) & 0xFF);
133 if ((i
+ 1) % 4 == 0)
136 for (size_t i
= 0; i
< 24; ++i
) {
137 if (data
[i
] >= 0x20 && data
[i
] <= 0x7E)
143 result
= base::StringPrintf("%d: ", (int)length
);
144 for (size_t i
= 0; i
< length
; ++i
) {
145 if (data
[i
] >= 0x20 && data
[i
] <= 0x7E)
151 LOG(ERROR
) << (outgoing
? "[out] " : "[ in] ") << result
;
155 void ReleaseInterface(scoped_refptr
<UsbDeviceHandle
> usb_device
,
157 usb_device
->ReleaseInterface(interface_id
);
163 AdbMessage::AdbMessage(uint32 command
,
166 const std::string
& body
)
173 AdbMessage::~AdbMessage() {
176 static void RespondOnCallerThread(const AndroidUsbDevicesCallback
& callback
,
177 AndroidUsbDevices
* new_devices
) {
178 scoped_ptr
<AndroidUsbDevices
> devices(new_devices
);
180 // Add raw pointers to the newly claimed devices.
181 for (AndroidUsbDevices::iterator it
= devices
->begin(); it
!= devices
->end();
183 g_devices
.Get().push_back(it
->get());
186 // Return all claimed devices.
187 AndroidUsbDevices
result(g_devices
.Get().begin(), g_devices
.Get().end());
188 callback
.Run(result
);
191 static void RespondOnFileThread(
192 const AndroidUsbDevicesCallback
& callback
,
193 AndroidUsbDevices
* devices
,
194 scoped_refptr
<base::MessageLoopProxy
> caller_message_loop_proxy
) {
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
196 caller_message_loop_proxy
->PostTask(
198 base::Bind(&RespondOnCallerThread
, callback
, devices
));
201 static void OpenAndroidDeviceOnFileThread(
202 AndroidUsbDevices
* devices
,
203 crypto::RSAPrivateKey
* rsa_key
,
204 const base::Closure
& barrier
,
205 scoped_refptr
<UsbDevice
> device
,
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
210 scoped_refptr
<UsbConfigDescriptor
> config
= device
->ListInterfaces();
211 scoped_refptr
<UsbDeviceHandle
> usb_handle
= device
->Open();
212 if (usb_handle
.get()) {
213 scoped_refptr
<AndroidUsbDevice
> android_device
=
214 ClaimInterface(rsa_key
, usb_handle
, config
->GetInterface(interface_id
),
216 if (android_device
.get())
217 devices
->push_back(android_device
.get());
225 static int CountOnFileThread() {
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
227 UsbService
* service
= UsbService::GetInstance();
228 UsbDevices usb_devices
;
230 service
->GetDevices(&usb_devices
);
231 int device_count
= 0;
232 for (UsbDevices::iterator it
= usb_devices
.begin(); it
!= usb_devices
.end();
234 scoped_refptr
<UsbConfigDescriptor
> config
= (*it
)->ListInterfaces();
238 for (size_t j
= 0; j
< config
->GetNumInterfaces(); ++j
) {
239 if (IsAndroidInterface(config
->GetInterface(j
)))
246 static void EnumerateOnFileThread(
247 crypto::RSAPrivateKey
* rsa_key
,
248 const AndroidUsbDevicesCallback
& callback
,
249 scoped_refptr
<base::MessageLoopProxy
> caller_message_loop_proxy
) {
250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
252 UsbService
* service
= UsbService::GetInstance();
253 UsbDevices usb_devices
;
255 service
->GetDevices(&usb_devices
);
258 AndroidUsbDevices
* devices
= new AndroidUsbDevices();
259 base::Closure barrier
= base::BarrierClosure(
260 usb_devices
.size(), base::Bind(&RespondOnFileThread
,
263 caller_message_loop_proxy
));
265 for (UsbDevices::iterator it
= usb_devices
.begin(); it
!= usb_devices
.end();
267 scoped_refptr
<UsbConfigDescriptor
> config
= (*it
)->ListInterfaces();
273 bool has_android_interface
= false;
274 for (size_t j
= 0; j
< config
->GetNumInterfaces(); ++j
) {
275 if (!IsAndroidInterface(config
->GetInterface(j
)))
278 // Request permission on Chrome OS.
279 #if defined(OS_CHROMEOS)
280 (*it
)->RequestUsbAccess(j
, base::Bind(&OpenAndroidDeviceOnFileThread
,
281 devices
, rsa_key
, barrier
, *it
, j
));
283 OpenAndroidDeviceOnFileThread(devices
, rsa_key
, barrier
, *it
, j
, true);
284 #endif // defined(OS_CHROMEOS)
286 has_android_interface
= true;
289 if (!has_android_interface
)
295 void AndroidUsbDevice::CountDevices(
296 const base::Callback
<void(int)>& callback
) {
297 BrowserThread::PostTaskAndReplyWithResult(
300 base::Bind(&CountOnFileThread
),
305 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey
* rsa_key
,
306 const AndroidUsbDevicesCallback
& callback
) {
308 // Collect devices with closed handles.
309 for (std::vector
<AndroidUsbDevice
*>::iterator it
= g_devices
.Get().begin();
310 it
!= g_devices
.Get().end(); ++it
) {
311 if ((*it
)->usb_handle_
.get()) {
312 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
313 base::Bind(&AndroidUsbDevice::TerminateIfReleased
, *it
,
314 (*it
)->usb_handle_
));
318 // Then look for the new devices.
319 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
320 base::Bind(&EnumerateOnFileThread
, rsa_key
, callback
,
321 base::MessageLoopProxy::current()));
324 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey
* rsa_key
,
325 scoped_refptr
<UsbDeviceHandle
> usb_device
,
326 const std::string
& serial
,
328 int outbound_address
,
331 : message_loop_(NULL
),
332 rsa_key_(rsa_key
->Copy()),
333 usb_handle_(usb_device
),
335 inbound_address_(inbound_address
),
336 outbound_address_(outbound_address
),
337 zero_mask_(zero_mask
),
338 interface_id_(interface_id
),
339 is_connected_(false),
340 signature_sent_(false),
341 last_socket_id_(256),
342 weak_factory_(this) {
345 void AndroidUsbDevice::InitOnCallerThread() {
348 message_loop_
= base::MessageLoop::current();
349 Queue(new AdbMessage(AdbMessage::kCommandCNXN
, kVersion
, kMaxPayload
,
350 kHostConnectMessage
));
354 net::StreamSocket
* AndroidUsbDevice::CreateSocket(const std::string
& command
) {
355 if (!usb_handle_
.get())
358 uint32 socket_id
= ++last_socket_id_
;
359 sockets_
[socket_id
] = new AndroidUsbSocket(this, socket_id
, command
,
360 base::Bind(&AndroidUsbDevice::SocketDeleted
, this));
361 return sockets_
[socket_id
];
364 void AndroidUsbDevice::Send(uint32 command
,
367 const std::string
& body
) {
368 scoped_refptr
<AdbMessage
> m
= new AdbMessage(command
, arg0
, arg1
, body
);
369 // Delay open request if not yet connected.
370 if (!is_connected_
) {
371 pending_messages_
.push_back(m
);
377 AndroidUsbDevice::~AndroidUsbDevice() {
378 DCHECK(message_loop_
== base::MessageLoop::current());
382 void AndroidUsbDevice::Queue(scoped_refptr
<AdbMessage
> message
) {
383 DCHECK(message_loop_
== base::MessageLoop::current());
386 std::vector
<uint32
> header
;
387 header
.push_back(message
->command
);
388 header
.push_back(message
->arg0
);
389 header
.push_back(message
->arg1
);
390 bool append_zero
= true;
391 if (message
->body
.empty())
393 if (message
->command
== AdbMessage::kCommandAUTH
&&
394 message
->arg0
== AdbMessage::kAuthSignature
)
396 if (message
->command
== AdbMessage::kCommandWRTE
)
399 size_t body_length
= message
->body
.length() + (append_zero
? 1 : 0);
400 header
.push_back(body_length
);
401 header
.push_back(Checksum(message
->body
));
402 header
.push_back(message
->command
^ 0xffffffff);
403 scoped_refptr
<net::IOBufferWithSize
> header_buffer
=
404 new net::IOBufferWithSize(kHeaderSize
);
405 memcpy(header_buffer
.get()->data(), &header
[0], kHeaderSize
);
406 outgoing_queue_
.push(header_buffer
);
409 if (!message
->body
.empty()) {
410 scoped_refptr
<net::IOBufferWithSize
> body_buffer
=
411 new net::IOBufferWithSize(body_length
);
412 memcpy(body_buffer
->data(), message
->body
.data(), message
->body
.length());
414 body_buffer
->data()[body_length
- 1] = 0;
415 outgoing_queue_
.push(body_buffer
);
416 if (zero_mask_
&& (body_length
& zero_mask_
) == 0) {
417 // Send a zero length packet.
418 outgoing_queue_
.push(new net::IOBufferWithSize(0));
424 void AndroidUsbDevice::ProcessOutgoing() {
425 DCHECK(message_loop_
== base::MessageLoop::current());
427 if (outgoing_queue_
.empty() || !usb_handle_
.get())
430 BulkMessage message
= outgoing_queue_
.front();
431 outgoing_queue_
.pop();
432 DumpMessage(true, message
->data(), message
->size());
433 usb_handle_
->BulkTransfer(usb_service::USB_DIRECTION_OUTBOUND
,
438 base::Bind(&AndroidUsbDevice::OutgoingMessageSent
,
439 weak_factory_
.GetWeakPtr()));
442 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status
,
443 scoped_refptr
<net::IOBuffer
> buffer
,
445 DCHECK(message_loop_
== base::MessageLoop::current());
447 if (status
!= usb_service::USB_TRANSFER_COMPLETED
)
449 message_loop_
->PostTask(FROM_HERE
,
450 base::Bind(&AndroidUsbDevice::ProcessOutgoing
, this));
453 void AndroidUsbDevice::ReadHeader() {
454 DCHECK(message_loop_
== base::MessageLoop::current());
456 if (!usb_handle_
.get())
458 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(kHeaderSize
);
459 usb_handle_
->BulkTransfer(
460 usb_service::USB_DIRECTION_INBOUND
,
465 base::Bind(&AndroidUsbDevice::ParseHeader
, weak_factory_
.GetWeakPtr()));
468 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status
,
469 scoped_refptr
<net::IOBuffer
> buffer
,
471 DCHECK(message_loop_
== base::MessageLoop::current());
473 if (status
== usb_service::USB_TRANSFER_TIMEOUT
) {
474 message_loop_
->PostTask(FROM_HERE
,
475 base::Bind(&AndroidUsbDevice::ReadHeader
, this));
479 if (status
!= usb_service::USB_TRANSFER_COMPLETED
|| result
!= kHeaderSize
) {
480 TransferError(status
);
484 DumpMessage(false, buffer
->data(), result
);
485 std::vector
<uint32
> header(6);
486 memcpy(&header
[0], buffer
->data(), result
);
487 scoped_refptr
<AdbMessage
> message
=
488 new AdbMessage(header
[0], header
[1], header
[2], "");
489 uint32 data_length
= header
[3];
490 uint32 data_check
= header
[4];
491 uint32 magic
= header
[5];
492 if ((message
->command
^ 0xffffffff) != magic
) {
493 TransferError(usb_service::USB_TRANSFER_ERROR
);
497 if (data_length
== 0) {
498 message_loop_
->PostTask(FROM_HERE
,
499 base::Bind(&AndroidUsbDevice::HandleIncoming
, this,
504 message_loop_
->PostTask(FROM_HERE
,
505 base::Bind(&AndroidUsbDevice::ReadBody
, this,
506 message
, data_length
, data_check
));
509 void AndroidUsbDevice::ReadBody(scoped_refptr
<AdbMessage
> message
,
512 DCHECK(message_loop_
== base::MessageLoop::current());
514 if (!usb_handle_
.get())
516 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(data_length
);
517 usb_handle_
->BulkTransfer(usb_service::USB_DIRECTION_INBOUND
,
522 base::Bind(&AndroidUsbDevice::ParseBody
,
523 weak_factory_
.GetWeakPtr(),
529 void AndroidUsbDevice::ParseBody(scoped_refptr
<AdbMessage
> message
,
532 UsbTransferStatus status
,
533 scoped_refptr
<net::IOBuffer
> buffer
,
535 DCHECK(message_loop_
== base::MessageLoop::current());
537 if (status
== usb_service::USB_TRANSFER_TIMEOUT
) {
538 message_loop_
->PostTask(FROM_HERE
,
539 base::Bind(&AndroidUsbDevice::ReadBody
, this,
540 message
, data_length
, data_check
));
544 if (status
!= usb_service::USB_TRANSFER_COMPLETED
||
545 static_cast<uint32
>(result
) != data_length
) {
546 TransferError(status
);
550 DumpMessage(false, buffer
->data(), data_length
);
551 message
->body
= std::string(buffer
->data(), result
);
552 if (Checksum(message
->body
) != data_check
) {
553 TransferError(usb_service::USB_TRANSFER_ERROR
);
557 message_loop_
->PostTask(FROM_HERE
,
558 base::Bind(&AndroidUsbDevice::HandleIncoming
, this,
562 void AndroidUsbDevice::HandleIncoming(scoped_refptr
<AdbMessage
> message
) {
563 DCHECK(message_loop_
== base::MessageLoop::current());
565 switch (message
->command
) {
566 case AdbMessage::kCommandAUTH
:
568 DCHECK_EQ(message
->arg0
, static_cast<uint32
>(AdbMessage::kAuthToken
));
569 if (signature_sent_
) {
570 Queue(new AdbMessage(AdbMessage::kCommandAUTH
,
571 AdbMessage::kAuthRSAPublicKey
, 0,
572 AndroidRSAPublicKey(rsa_key_
.get())));
574 signature_sent_
= true;
575 std::string signature
= AndroidRSASign(rsa_key_
.get(), message
->body
);
576 if (!signature
.empty()) {
577 Queue(new AdbMessage(AdbMessage::kCommandAUTH
,
578 AdbMessage::kAuthSignature
, 0,
581 Queue(new AdbMessage(AdbMessage::kCommandAUTH
,
582 AdbMessage::kAuthRSAPublicKey
, 0,
583 AndroidRSAPublicKey(rsa_key_
.get())));
588 case AdbMessage::kCommandCNXN
:
590 is_connected_
= true;
591 PendingMessages pending
;
592 pending
.swap(pending_messages_
);
593 for (PendingMessages::iterator it
= pending
.begin();
594 it
!= pending
.end(); ++it
) {
599 case AdbMessage::kCommandOKAY
:
600 case AdbMessage::kCommandWRTE
:
601 case AdbMessage::kCommandCLSE
:
603 AndroidUsbSockets::iterator it
= sockets_
.find(message
->arg1
);
604 if (it
!= sockets_
.end())
605 it
->second
->HandleIncoming(message
);
614 void AndroidUsbDevice::TransferError(UsbTransferStatus status
) {
615 DCHECK(message_loop_
== base::MessageLoop::current());
617 message_loop_
->PostTask(FROM_HERE
,
618 base::Bind(&AndroidUsbDevice::Terminate
, this));
621 void AndroidUsbDevice::TerminateIfReleased(
622 scoped_refptr
<UsbDeviceHandle
> usb_handle
) {
623 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
624 if (usb_handle
->GetDevice().get())
626 message_loop_
->PostTask(FROM_HERE
,
627 base::Bind(&AndroidUsbDevice::Terminate
, this));
630 void AndroidUsbDevice::Terminate() {
631 DCHECK(message_loop_
== base::MessageLoop::current());
633 std::vector
<AndroidUsbDevice
*>::iterator it
=
634 std::find(g_devices
.Get().begin(), g_devices
.Get().end(), this);
635 if (it
!= g_devices
.Get().end())
636 g_devices
.Get().erase(it
);
638 if (!usb_handle_
.get())
641 // Make sure we zero-out handle so that closing connections did not open
643 scoped_refptr
<UsbDeviceHandle
> usb_handle
= usb_handle_
;
646 // Iterate over copy.
647 AndroidUsbSockets
sockets(sockets_
);
648 for (AndroidUsbSockets::iterator it
= sockets
.begin();
649 it
!= sockets
.end(); ++it
) {
650 it
->second
->Terminated(true);
652 DCHECK(sockets_
.empty());
654 BrowserThread::PostTask(
655 BrowserThread::FILE, FROM_HERE
,
656 base::Bind(&ReleaseInterface
, usb_handle
, interface_id_
));
659 void AndroidUsbDevice::SocketDeleted(uint32 socket_id
) {
660 DCHECK(message_loop_
== base::MessageLoop::current());
662 sockets_
.erase(socket_id
);