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 "content/public/browser/browser_thread.h"
20 #include "crypto/rsa_private_key.h"
21 #include "device/core/device_client.h"
22 #include "device/usb/usb_descriptors.h"
23 #include "device/usb/usb_device.h"
24 #include "device/usb/usb_service.h"
25 #include "net/base/ip_endpoint.h"
26 #include "net/base/net_errors.h"
27 #include "net/socket/stream_socket.h"
29 using device::UsbConfigDescriptor
;
30 using device::UsbDevice
;
31 using device::UsbDeviceHandle
;
32 using device::UsbInterfaceDescriptor
;
33 using device::UsbEndpointDescriptor
;
34 using device::UsbService
;
35 using device::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(const UsbInterfaceDescriptor
& interface
) {
62 if (interface
.alternate_setting
!= 0 ||
63 interface
.interface_class
!= kAdbClass
||
64 interface
.interface_subclass
!= kAdbSubclass
||
65 interface
.interface_protocol
!= kAdbProtocol
||
66 interface
.endpoints
.size() != 2) {
72 scoped_refptr
<AndroidUsbDevice
> ClaimInterface(
73 crypto::RSAPrivateKey
* rsa_key
,
74 scoped_refptr
<UsbDeviceHandle
> usb_handle
,
75 const base::string16
& serial
,
76 const UsbInterfaceDescriptor
& interface
) {
77 int inbound_address
= 0;
78 int outbound_address
= 0;
81 for (const UsbEndpointDescriptor
& endpoint
: interface
.endpoints
) {
82 if (endpoint
.transfer_type
!= device::USB_TRANSFER_BULK
)
84 if (endpoint
.direction
== device::USB_DIRECTION_INBOUND
)
85 inbound_address
= endpoint
.address
;
87 outbound_address
= endpoint
.address
;
88 zero_mask
= endpoint
.maximum_packet_size
- 1;
91 if (inbound_address
== 0 || outbound_address
== 0)
94 if (!usb_handle
->ClaimInterface(interface
.interface_number
))
97 return new AndroidUsbDevice(rsa_key
,
99 base::UTF16ToASCII(serial
),
103 interface
.interface_number
);
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
,
146 usb_device
->ReleaseInterface(interface_id
);
152 AdbMessage::AdbMessage(uint32 command
,
155 const std::string
& body
)
162 AdbMessage::~AdbMessage() {
165 static void RespondOnCallerThread(const AndroidUsbDevicesCallback
& callback
,
166 AndroidUsbDevices
* new_devices
) {
167 scoped_ptr
<AndroidUsbDevices
> devices(new_devices
);
169 // Add raw pointers to the newly claimed devices.
170 for (const scoped_refptr
<AndroidUsbDevice
>& device
: *devices
) {
171 g_devices
.Get().push_back(device
.get());
174 // Return all claimed devices.
175 AndroidUsbDevices
result(g_devices
.Get().begin(), g_devices
.Get().end());
176 callback
.Run(result
);
179 static void RespondOnFileThread(
180 const AndroidUsbDevicesCallback
& callback
,
181 AndroidUsbDevices
* devices
,
182 scoped_refptr
<base::MessageLoopProxy
> caller_message_loop_proxy
) {
183 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
184 caller_message_loop_proxy
->PostTask(
186 base::Bind(&RespondOnCallerThread
, callback
, devices
));
189 static void OpenAndroidDeviceOnFileThread(
190 AndroidUsbDevices
* devices
,
191 crypto::RSAPrivateKey
* rsa_key
,
192 const base::Closure
& barrier
,
193 scoped_refptr
<UsbDevice
> device
,
196 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
198 base::string16 serial
;
199 if (device
->GetSerialNumber(&serial
) && !serial
.empty()) {
200 const UsbConfigDescriptor
* config
= device
->GetConfiguration();
202 scoped_refptr
<UsbDeviceHandle
> usb_handle
= device
->Open();
203 if (usb_handle
.get()) {
204 scoped_refptr
<AndroidUsbDevice
> android_device
= ClaimInterface(
205 rsa_key
, usb_handle
, serial
, config
->interfaces
[interface_id
]);
206 if (android_device
.get())
207 devices
->push_back(android_device
);
217 static int CountOnFileThread() {
218 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
219 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
220 UsbDevices usb_devices
;
222 service
->GetDevices(&usb_devices
);
223 int device_count
= 0;
224 for (const scoped_refptr
<UsbDevice
>& device
: usb_devices
) {
225 const UsbConfigDescriptor
* config
= device
->GetConfiguration();
227 for (const UsbInterfaceDescriptor
& iface
: config
->interfaces
) {
228 if (IsAndroidInterface(iface
)) {
237 static void EnumerateOnFileThread(
238 crypto::RSAPrivateKey
* rsa_key
,
239 const AndroidUsbDevicesCallback
& callback
,
240 scoped_refptr
<base::MessageLoopProxy
> caller_message_loop_proxy
) {
241 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
243 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
244 UsbDevices usb_devices
;
246 service
->GetDevices(&usb_devices
);
249 AndroidUsbDevices
* devices
= new AndroidUsbDevices();
250 base::Closure barrier
= base::BarrierClosure(
251 usb_devices
.size(), base::Bind(&RespondOnFileThread
,
254 caller_message_loop_proxy
));
256 for (const scoped_refptr
<UsbDevice
>& device
: usb_devices
) {
257 const UsbConfigDescriptor
* config
= device
->GetConfiguration();
262 bool has_android_interface
= false;
263 for (size_t j
= 0; j
< config
->interfaces
.size(); ++j
) {
264 if (!IsAndroidInterface(config
->interfaces
[j
])) {
268 device
->RequestUsbAccess(
269 j
, base::Bind(&OpenAndroidDeviceOnFileThread
, devices
, rsa_key
,
270 barrier
, device
, j
));
272 has_android_interface
= true;
275 if (!has_android_interface
)
281 void AndroidUsbDevice::CountDevices(
282 const base::Callback
<void(int)>& callback
) {
283 BrowserThread::PostTaskAndReplyWithResult(
286 base::Bind(&CountOnFileThread
),
291 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey
* rsa_key
,
292 const AndroidUsbDevicesCallback
& callback
) {
294 // Collect devices with closed handles.
295 for (AndroidUsbDevice
* device
: g_devices
.Get()) {
296 if (device
->usb_handle_
.get()) {
297 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
298 base::Bind(&AndroidUsbDevice::TerminateIfReleased
, device
,
299 device
->usb_handle_
));
303 // Then look for the new devices.
304 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
305 base::Bind(&EnumerateOnFileThread
, rsa_key
, callback
,
306 base::MessageLoopProxy::current()));
309 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey
* rsa_key
,
310 scoped_refptr
<UsbDeviceHandle
> usb_device
,
311 const std::string
& serial
,
313 int outbound_address
,
316 : message_loop_(NULL
),
317 rsa_key_(rsa_key
->Copy()),
318 usb_handle_(usb_device
),
320 inbound_address_(inbound_address
),
321 outbound_address_(outbound_address
),
322 zero_mask_(zero_mask
),
323 interface_id_(interface_id
),
324 is_connected_(false),
325 signature_sent_(false),
326 last_socket_id_(256),
327 weak_factory_(this) {
330 void AndroidUsbDevice::InitOnCallerThread() {
333 message_loop_
= base::MessageLoop::current();
334 Queue(make_scoped_ptr(new AdbMessage(AdbMessage::kCommandCNXN
, kVersion
,
335 kMaxPayload
, kHostConnectMessage
)));
339 net::StreamSocket
* AndroidUsbDevice::CreateSocket(const std::string
& command
) {
340 if (!usb_handle_
.get())
343 uint32 socket_id
= ++last_socket_id_
;
344 sockets_
[socket_id
] = new AndroidUsbSocket(this, socket_id
, command
,
345 base::Bind(&AndroidUsbDevice::SocketDeleted
, this, socket_id
));
346 return sockets_
[socket_id
];
349 void AndroidUsbDevice::Send(uint32 command
,
352 const std::string
& body
) {
353 scoped_ptr
<AdbMessage
> message(new AdbMessage(command
, arg0
, arg1
, body
));
354 // Delay open request if not yet connected.
355 if (!is_connected_
) {
356 pending_messages_
.push_back(message
.release());
359 Queue(message
.Pass());
362 AndroidUsbDevice::~AndroidUsbDevice() {
363 DCHECK(message_loop_
== base::MessageLoop::current());
367 void AndroidUsbDevice::Queue(scoped_ptr
<AdbMessage
> message
) {
368 DCHECK(message_loop_
== base::MessageLoop::current());
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::IOBufferWithSize
> header_buffer
=
389 new net::IOBufferWithSize(kHeaderSize
);
390 memcpy(header_buffer
.get()->data(), &header
[0], kHeaderSize
);
391 outgoing_queue_
.push(header_buffer
);
394 if (!message
->body
.empty()) {
395 scoped_refptr
<net::IOBufferWithSize
> body_buffer
=
396 new net::IOBufferWithSize(body_length
);
397 memcpy(body_buffer
->data(), message
->body
.data(), message
->body
.length());
399 body_buffer
->data()[body_length
- 1] = 0;
400 outgoing_queue_
.push(body_buffer
);
401 if (zero_mask_
&& (body_length
& zero_mask_
) == 0) {
402 // Send a zero length packet.
403 outgoing_queue_
.push(new net::IOBufferWithSize(0));
409 void AndroidUsbDevice::ProcessOutgoing() {
410 DCHECK(message_loop_
== base::MessageLoop::current());
412 if (outgoing_queue_
.empty() || !usb_handle_
.get())
415 BulkMessage message
= outgoing_queue_
.front();
416 outgoing_queue_
.pop();
417 DumpMessage(true, message
->data(), message
->size());
418 usb_handle_
->BulkTransfer(device::USB_DIRECTION_OUTBOUND
,
423 base::Bind(&AndroidUsbDevice::OutgoingMessageSent
,
424 weak_factory_
.GetWeakPtr()));
427 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status
,
428 scoped_refptr
<net::IOBuffer
> buffer
,
430 DCHECK(message_loop_
== base::MessageLoop::current());
432 if (status
!= device::USB_TRANSFER_COMPLETED
)
434 message_loop_
->PostTask(FROM_HERE
,
435 base::Bind(&AndroidUsbDevice::ProcessOutgoing
, this));
438 void AndroidUsbDevice::ReadHeader() {
439 DCHECK(message_loop_
== base::MessageLoop::current());
441 if (!usb_handle_
.get())
443 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(kHeaderSize
);
444 usb_handle_
->BulkTransfer(
445 device::USB_DIRECTION_INBOUND
,
450 base::Bind(&AndroidUsbDevice::ParseHeader
, weak_factory_
.GetWeakPtr()));
453 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status
,
454 scoped_refptr
<net::IOBuffer
> buffer
,
456 DCHECK(message_loop_
== base::MessageLoop::current());
458 if (status
== device::USB_TRANSFER_TIMEOUT
) {
459 message_loop_
->PostTask(FROM_HERE
,
460 base::Bind(&AndroidUsbDevice::ReadHeader
, this));
464 if (status
!= device::USB_TRANSFER_COMPLETED
|| result
!= kHeaderSize
) {
465 TransferError(status
);
469 DumpMessage(false, buffer
->data(), result
);
470 std::vector
<uint32
> header(6);
471 memcpy(&header
[0], buffer
->data(), result
);
472 scoped_ptr
<AdbMessage
> message(
473 new AdbMessage(header
[0], header
[1], header
[2], ""));
474 uint32 data_length
= header
[3];
475 uint32 data_check
= header
[4];
476 uint32 magic
= header
[5];
477 if ((message
->command
^ 0xffffffff) != magic
) {
478 TransferError(device::USB_TRANSFER_ERROR
);
482 if (data_length
== 0) {
483 message_loop_
->PostTask(FROM_HERE
,
484 base::Bind(&AndroidUsbDevice::HandleIncoming
, this,
485 base::Passed(&message
)));
489 message_loop_
->PostTask(FROM_HERE
,
490 base::Bind(&AndroidUsbDevice::ReadBody
, this,
491 base::Passed(&message
), data_length
, data_check
));
494 void AndroidUsbDevice::ReadBody(scoped_ptr
<AdbMessage
> message
,
497 DCHECK(message_loop_
== base::MessageLoop::current());
499 if (!usb_handle_
.get())
501 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(data_length
);
502 usb_handle_
->BulkTransfer(device::USB_DIRECTION_INBOUND
,
507 base::Bind(&AndroidUsbDevice::ParseBody
,
508 weak_factory_
.GetWeakPtr(),
509 base::Passed(&message
),
514 void AndroidUsbDevice::ParseBody(scoped_ptr
<AdbMessage
> message
,
517 UsbTransferStatus status
,
518 scoped_refptr
<net::IOBuffer
> buffer
,
520 DCHECK(message_loop_
== base::MessageLoop::current());
522 if (status
== device::USB_TRANSFER_TIMEOUT
) {
523 message_loop_
->PostTask(FROM_HERE
,
524 base::Bind(&AndroidUsbDevice::ReadBody
, this,
525 base::Passed(&message
), data_length
, data_check
));
529 if (status
!= device::USB_TRANSFER_COMPLETED
||
530 static_cast<uint32
>(result
) != data_length
) {
531 TransferError(status
);
535 DumpMessage(false, buffer
->data(), data_length
);
536 message
->body
= std::string(buffer
->data(), result
);
537 if (Checksum(message
->body
) != data_check
) {
538 TransferError(device::USB_TRANSFER_ERROR
);
542 message_loop_
->PostTask(FROM_HERE
,
543 base::Bind(&AndroidUsbDevice::HandleIncoming
, this,
544 base::Passed(&message
)));
547 void AndroidUsbDevice::HandleIncoming(scoped_ptr
<AdbMessage
> message
) {
548 DCHECK(message_loop_
== base::MessageLoop::current());
550 switch (message
->command
) {
551 case AdbMessage::kCommandAUTH
:
553 DCHECK_EQ(message
->arg0
, static_cast<uint32
>(AdbMessage::kAuthToken
));
554 if (signature_sent_
) {
555 Queue(make_scoped_ptr(new AdbMessage(
556 AdbMessage::kCommandAUTH
,
557 AdbMessage::kAuthRSAPublicKey
, 0,
558 AndroidRSAPublicKey(rsa_key_
.get()))));
560 signature_sent_
= true;
561 std::string signature
= AndroidRSASign(rsa_key_
.get(), message
->body
);
562 if (!signature
.empty()) {
563 Queue(make_scoped_ptr(new AdbMessage(AdbMessage::kCommandAUTH
,
564 AdbMessage::kAuthSignature
, 0,
567 Queue(make_scoped_ptr(new AdbMessage(
568 AdbMessage::kCommandAUTH
,
569 AdbMessage::kAuthRSAPublicKey
, 0,
570 AndroidRSAPublicKey(rsa_key_
.get()))));
575 case AdbMessage::kCommandCNXN
:
577 is_connected_
= true;
578 PendingMessages pending
;
579 pending
.swap(pending_messages_
);
580 for (PendingMessages::iterator it
= pending
.begin();
581 it
!= pending
.end(); ++it
) {
582 Queue(make_scoped_ptr(*it
));
586 case AdbMessage::kCommandOKAY
:
587 case AdbMessage::kCommandWRTE
:
588 case AdbMessage::kCommandCLSE
:
590 AndroidUsbSockets::iterator it
= sockets_
.find(message
->arg1
);
591 if (it
!= sockets_
.end())
592 it
->second
->HandleIncoming(message
.Pass());
601 void AndroidUsbDevice::TransferError(UsbTransferStatus status
) {
602 DCHECK(message_loop_
== base::MessageLoop::current());
604 message_loop_
->PostTask(FROM_HERE
,
605 base::Bind(&AndroidUsbDevice::Terminate
, this));
608 void AndroidUsbDevice::TerminateIfReleased(
609 scoped_refptr
<UsbDeviceHandle
> usb_handle
) {
610 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
611 if (usb_handle
->GetDevice().get())
613 message_loop_
->PostTask(FROM_HERE
,
614 base::Bind(&AndroidUsbDevice::Terminate
, this));
617 void AndroidUsbDevice::Terminate() {
618 DCHECK(message_loop_
== base::MessageLoop::current());
620 std::vector
<AndroidUsbDevice
*>::iterator it
=
621 std::find(g_devices
.Get().begin(), g_devices
.Get().end(), this);
622 if (it
!= g_devices
.Get().end())
623 g_devices
.Get().erase(it
);
625 if (!usb_handle_
.get())
628 // Make sure we zero-out handle so that closing connections did not open
630 scoped_refptr
<UsbDeviceHandle
> usb_handle
= usb_handle_
;
633 // Iterate over copy.
634 AndroidUsbSockets
sockets(sockets_
);
635 for (AndroidUsbSockets::iterator it
= sockets
.begin();
636 it
!= sockets
.end(); ++it
) {
637 it
->second
->Terminated(true);
639 DCHECK(sockets_
.empty());
641 BrowserThread::PostTask(
642 BrowserThread::FILE, FROM_HERE
,
643 base::Bind(&ReleaseInterface
, usb_handle
, interface_id_
));
646 void AndroidUsbDevice::SocketDeleted(uint32 socket_id
) {
647 DCHECK(message_loop_
== base::MessageLoop::current());
649 sockets_
.erase(socket_id
);