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 // Request permission on Chrome OS.
269 #if defined(OS_CHROMEOS)
270 device
->RequestUsbAccess(
271 j
, base::Bind(&OpenAndroidDeviceOnFileThread
, devices
, rsa_key
,
272 barrier
, device
, j
));
274 OpenAndroidDeviceOnFileThread(devices
, rsa_key
, barrier
, device
, j
, true);
275 #endif // defined(OS_CHROMEOS)
277 has_android_interface
= true;
280 if (!has_android_interface
)
286 void AndroidUsbDevice::CountDevices(
287 const base::Callback
<void(int)>& callback
) {
288 BrowserThread::PostTaskAndReplyWithResult(
291 base::Bind(&CountOnFileThread
),
296 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey
* rsa_key
,
297 const AndroidUsbDevicesCallback
& callback
) {
299 // Collect devices with closed handles.
300 for (AndroidUsbDevice
* device
: g_devices
.Get()) {
301 if (device
->usb_handle_
.get()) {
302 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
303 base::Bind(&AndroidUsbDevice::TerminateIfReleased
, device
,
304 device
->usb_handle_
));
308 // Then look for the new devices.
309 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
310 base::Bind(&EnumerateOnFileThread
, rsa_key
, callback
,
311 base::MessageLoopProxy::current()));
314 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey
* rsa_key
,
315 scoped_refptr
<UsbDeviceHandle
> usb_device
,
316 const std::string
& serial
,
318 int outbound_address
,
321 : message_loop_(NULL
),
322 rsa_key_(rsa_key
->Copy()),
323 usb_handle_(usb_device
),
325 inbound_address_(inbound_address
),
326 outbound_address_(outbound_address
),
327 zero_mask_(zero_mask
),
328 interface_id_(interface_id
),
329 is_connected_(false),
330 signature_sent_(false),
331 last_socket_id_(256),
332 weak_factory_(this) {
335 void AndroidUsbDevice::InitOnCallerThread() {
338 message_loop_
= base::MessageLoop::current();
339 Queue(make_scoped_ptr(new AdbMessage(AdbMessage::kCommandCNXN
, kVersion
,
340 kMaxPayload
, kHostConnectMessage
)));
344 net::StreamSocket
* AndroidUsbDevice::CreateSocket(const std::string
& command
) {
345 if (!usb_handle_
.get())
348 uint32 socket_id
= ++last_socket_id_
;
349 sockets_
[socket_id
] = new AndroidUsbSocket(this, socket_id
, command
,
350 base::Bind(&AndroidUsbDevice::SocketDeleted
, this, socket_id
));
351 return sockets_
[socket_id
];
354 void AndroidUsbDevice::Send(uint32 command
,
357 const std::string
& body
) {
358 scoped_ptr
<AdbMessage
> message(new AdbMessage(command
, arg0
, arg1
, body
));
359 // Delay open request if not yet connected.
360 if (!is_connected_
) {
361 pending_messages_
.push_back(message
.release());
364 Queue(message
.Pass());
367 AndroidUsbDevice::~AndroidUsbDevice() {
368 DCHECK(message_loop_
== base::MessageLoop::current());
372 void AndroidUsbDevice::Queue(scoped_ptr
<AdbMessage
> message
) {
373 DCHECK(message_loop_
== base::MessageLoop::current());
376 std::vector
<uint32
> header
;
377 header
.push_back(message
->command
);
378 header
.push_back(message
->arg0
);
379 header
.push_back(message
->arg1
);
380 bool append_zero
= true;
381 if (message
->body
.empty())
383 if (message
->command
== AdbMessage::kCommandAUTH
&&
384 message
->arg0
== AdbMessage::kAuthSignature
)
386 if (message
->command
== AdbMessage::kCommandWRTE
)
389 size_t body_length
= message
->body
.length() + (append_zero
? 1 : 0);
390 header
.push_back(body_length
);
391 header
.push_back(Checksum(message
->body
));
392 header
.push_back(message
->command
^ 0xffffffff);
393 scoped_refptr
<net::IOBufferWithSize
> header_buffer
=
394 new net::IOBufferWithSize(kHeaderSize
);
395 memcpy(header_buffer
.get()->data(), &header
[0], kHeaderSize
);
396 outgoing_queue_
.push(header_buffer
);
399 if (!message
->body
.empty()) {
400 scoped_refptr
<net::IOBufferWithSize
> body_buffer
=
401 new net::IOBufferWithSize(body_length
);
402 memcpy(body_buffer
->data(), message
->body
.data(), message
->body
.length());
404 body_buffer
->data()[body_length
- 1] = 0;
405 outgoing_queue_
.push(body_buffer
);
406 if (zero_mask_
&& (body_length
& zero_mask_
) == 0) {
407 // Send a zero length packet.
408 outgoing_queue_
.push(new net::IOBufferWithSize(0));
414 void AndroidUsbDevice::ProcessOutgoing() {
415 DCHECK(message_loop_
== base::MessageLoop::current());
417 if (outgoing_queue_
.empty() || !usb_handle_
.get())
420 BulkMessage message
= outgoing_queue_
.front();
421 outgoing_queue_
.pop();
422 DumpMessage(true, message
->data(), message
->size());
423 usb_handle_
->BulkTransfer(device::USB_DIRECTION_OUTBOUND
,
428 base::Bind(&AndroidUsbDevice::OutgoingMessageSent
,
429 weak_factory_
.GetWeakPtr()));
432 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status
,
433 scoped_refptr
<net::IOBuffer
> buffer
,
435 DCHECK(message_loop_
== base::MessageLoop::current());
437 if (status
!= device::USB_TRANSFER_COMPLETED
)
439 message_loop_
->PostTask(FROM_HERE
,
440 base::Bind(&AndroidUsbDevice::ProcessOutgoing
, this));
443 void AndroidUsbDevice::ReadHeader() {
444 DCHECK(message_loop_
== base::MessageLoop::current());
446 if (!usb_handle_
.get())
448 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(kHeaderSize
);
449 usb_handle_
->BulkTransfer(
450 device::USB_DIRECTION_INBOUND
,
455 base::Bind(&AndroidUsbDevice::ParseHeader
, weak_factory_
.GetWeakPtr()));
458 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status
,
459 scoped_refptr
<net::IOBuffer
> buffer
,
461 DCHECK(message_loop_
== base::MessageLoop::current());
463 if (status
== device::USB_TRANSFER_TIMEOUT
) {
464 message_loop_
->PostTask(FROM_HERE
,
465 base::Bind(&AndroidUsbDevice::ReadHeader
, this));
469 if (status
!= device::USB_TRANSFER_COMPLETED
|| result
!= kHeaderSize
) {
470 TransferError(status
);
474 DumpMessage(false, buffer
->data(), result
);
475 std::vector
<uint32
> header(6);
476 memcpy(&header
[0], buffer
->data(), result
);
477 scoped_ptr
<AdbMessage
> message(
478 new AdbMessage(header
[0], header
[1], header
[2], ""));
479 uint32 data_length
= header
[3];
480 uint32 data_check
= header
[4];
481 uint32 magic
= header
[5];
482 if ((message
->command
^ 0xffffffff) != magic
) {
483 TransferError(device::USB_TRANSFER_ERROR
);
487 if (data_length
== 0) {
488 message_loop_
->PostTask(FROM_HERE
,
489 base::Bind(&AndroidUsbDevice::HandleIncoming
, this,
490 base::Passed(&message
)));
494 message_loop_
->PostTask(FROM_HERE
,
495 base::Bind(&AndroidUsbDevice::ReadBody
, this,
496 base::Passed(&message
), data_length
, data_check
));
499 void AndroidUsbDevice::ReadBody(scoped_ptr
<AdbMessage
> message
,
502 DCHECK(message_loop_
== base::MessageLoop::current());
504 if (!usb_handle_
.get())
506 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(data_length
);
507 usb_handle_
->BulkTransfer(device::USB_DIRECTION_INBOUND
,
512 base::Bind(&AndroidUsbDevice::ParseBody
,
513 weak_factory_
.GetWeakPtr(),
514 base::Passed(&message
),
519 void AndroidUsbDevice::ParseBody(scoped_ptr
<AdbMessage
> message
,
522 UsbTransferStatus status
,
523 scoped_refptr
<net::IOBuffer
> buffer
,
525 DCHECK(message_loop_
== base::MessageLoop::current());
527 if (status
== device::USB_TRANSFER_TIMEOUT
) {
528 message_loop_
->PostTask(FROM_HERE
,
529 base::Bind(&AndroidUsbDevice::ReadBody
, this,
530 base::Passed(&message
), data_length
, data_check
));
534 if (status
!= device::USB_TRANSFER_COMPLETED
||
535 static_cast<uint32
>(result
) != data_length
) {
536 TransferError(status
);
540 DumpMessage(false, buffer
->data(), data_length
);
541 message
->body
= std::string(buffer
->data(), result
);
542 if (Checksum(message
->body
) != data_check
) {
543 TransferError(device::USB_TRANSFER_ERROR
);
547 message_loop_
->PostTask(FROM_HERE
,
548 base::Bind(&AndroidUsbDevice::HandleIncoming
, this,
549 base::Passed(&message
)));
552 void AndroidUsbDevice::HandleIncoming(scoped_ptr
<AdbMessage
> message
) {
553 DCHECK(message_loop_
== base::MessageLoop::current());
555 switch (message
->command
) {
556 case AdbMessage::kCommandAUTH
:
558 DCHECK_EQ(message
->arg0
, static_cast<uint32
>(AdbMessage::kAuthToken
));
559 if (signature_sent_
) {
560 Queue(make_scoped_ptr(new AdbMessage(
561 AdbMessage::kCommandAUTH
,
562 AdbMessage::kAuthRSAPublicKey
, 0,
563 AndroidRSAPublicKey(rsa_key_
.get()))));
565 signature_sent_
= true;
566 std::string signature
= AndroidRSASign(rsa_key_
.get(), message
->body
);
567 if (!signature
.empty()) {
568 Queue(make_scoped_ptr(new AdbMessage(AdbMessage::kCommandAUTH
,
569 AdbMessage::kAuthSignature
, 0,
572 Queue(make_scoped_ptr(new AdbMessage(
573 AdbMessage::kCommandAUTH
,
574 AdbMessage::kAuthRSAPublicKey
, 0,
575 AndroidRSAPublicKey(rsa_key_
.get()))));
580 case AdbMessage::kCommandCNXN
:
582 is_connected_
= true;
583 PendingMessages pending
;
584 pending
.swap(pending_messages_
);
585 for (PendingMessages::iterator it
= pending
.begin();
586 it
!= pending
.end(); ++it
) {
587 Queue(make_scoped_ptr(*it
));
591 case AdbMessage::kCommandOKAY
:
592 case AdbMessage::kCommandWRTE
:
593 case AdbMessage::kCommandCLSE
:
595 AndroidUsbSockets::iterator it
= sockets_
.find(message
->arg1
);
596 if (it
!= sockets_
.end())
597 it
->second
->HandleIncoming(message
.Pass());
606 void AndroidUsbDevice::TransferError(UsbTransferStatus status
) {
607 DCHECK(message_loop_
== base::MessageLoop::current());
609 message_loop_
->PostTask(FROM_HERE
,
610 base::Bind(&AndroidUsbDevice::Terminate
, this));
613 void AndroidUsbDevice::TerminateIfReleased(
614 scoped_refptr
<UsbDeviceHandle
> usb_handle
) {
615 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
616 if (usb_handle
->GetDevice().get())
618 message_loop_
->PostTask(FROM_HERE
,
619 base::Bind(&AndroidUsbDevice::Terminate
, this));
622 void AndroidUsbDevice::Terminate() {
623 DCHECK(message_loop_
== base::MessageLoop::current());
625 std::vector
<AndroidUsbDevice
*>::iterator it
=
626 std::find(g_devices
.Get().begin(), g_devices
.Get().end(), this);
627 if (it
!= g_devices
.Get().end())
628 g_devices
.Get().erase(it
);
630 if (!usb_handle_
.get())
633 // Make sure we zero-out handle so that closing connections did not open
635 scoped_refptr
<UsbDeviceHandle
> usb_handle
= usb_handle_
;
638 // Iterate over copy.
639 AndroidUsbSockets
sockets(sockets_
);
640 for (AndroidUsbSockets::iterator it
= sockets
.begin();
641 it
!= sockets
.end(); ++it
) {
642 it
->second
->Terminated(true);
644 DCHECK(sockets_
.empty());
646 BrowserThread::PostTask(
647 BrowserThread::FILE, FROM_HERE
,
648 base::Bind(&ReleaseInterface
, usb_handle
, interface_id_
));
651 void AndroidUsbDevice::SocketDeleted(uint32 socket_id
) {
652 DCHECK(message_loop_
== base::MessageLoop::current());
654 sockets_
.erase(socket_id
);