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
;
211 service
->GetDevices(&usb_devices
);
212 int device_count
= 0;
213 for (UsbDevices::iterator it
= usb_devices
.begin(); it
!= usb_devices
.end();
215 scoped_refptr
<UsbConfigDescriptor
> config
= (*it
)->ListInterfaces();
219 for (size_t j
= 0; j
< config
->GetNumInterfaces(); ++j
) {
220 if (IsAndroidInterface(config
->GetInterface(j
)))
224 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
225 base::Bind(&RespondWithCountOnUIThread
, callback
,
229 static void EnumerateOnFileThread(crypto::RSAPrivateKey
* rsa_key
,
230 const AndroidUsbDevicesCallback
& callback
) {
231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
233 UsbService
* service
= UsbService::GetInstance();
234 UsbDevices usb_devices
;
236 service
->GetDevices(&usb_devices
);
238 AndroidUsbDevices
& devices
= g_devices
.Get();
240 // GC Android devices with no actual usb device.
241 AndroidUsbDevices::iterator it
= devices
.begin();
242 UsbDeviceSet claimed_devices
;
243 while (it
!= devices
.end()) {
244 bool found_device
= false;
245 for (UsbDevices::iterator it2
= usb_devices
.begin();
246 it2
!= usb_devices
.end() && !found_device
; ++it2
) {
247 UsbDevice
* usb_device
= it2
->get();
248 AndroidUsbDevice
* device
= it
->get();
249 if (usb_device
== device
->usb_device()->device()) {
251 claimed_devices
.insert(usb_device
);
256 it
= devices
.erase(it
);
262 base::Closure barrier
= base::BarrierClosure(
263 usb_devices
.size(), base::Bind(&RespondOnFileThread
, callback
));
265 for (UsbDevices::iterator it
= usb_devices
.begin(); it
!= usb_devices
.end();
267 if (ContainsKey(claimed_devices
, it
->get())) {
272 scoped_refptr
<UsbConfigDescriptor
> config
= (*it
)->ListInterfaces();
278 bool has_android_interface
= false;
279 for (size_t j
= 0; j
< config
->GetNumInterfaces(); ++j
) {
280 if (!IsAndroidInterface(config
->GetInterface(j
)))
283 // Request permission on Chrome OS.
284 #if defined(OS_CHROMEOS)
285 (*it
)->RequestUsbAcess(j
, base::Bind(&OpenAndroidDevicesOnFileThread
,
286 rsa_key
, barrier
, *it
, j
));
288 OpenAndroidDevicesOnFileThread(rsa_key
, barrier
, *it
, j
, true);
289 #endif // defined(OS_CHROMEOS)
291 has_android_interface
= true;
294 if (!has_android_interface
)
300 void AndroidUsbDevice::CountDevices(
301 const base::Callback
<void(int)>& callback
) {
302 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
303 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
304 base::Bind(&CountOnFileThread
, callback
));
308 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey
* rsa_key
,
309 const AndroidUsbDevicesCallback
& callback
) {
310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
311 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE
,
312 base::Bind(&EnumerateOnFileThread
, rsa_key
,
316 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey
* rsa_key
,
317 scoped_refptr
<UsbDeviceHandle
> usb_device
,
318 const std::string
& serial
,
320 int outbound_address
,
322 : message_loop_(NULL
),
323 rsa_key_(rsa_key
->Copy()),
324 usb_device_(usb_device
),
326 inbound_address_(inbound_address
),
327 outbound_address_(outbound_address
),
328 zero_mask_(zero_mask
),
329 is_connected_(false),
330 signature_sent_(false),
331 last_socket_id_(256),
335 void AndroidUsbDevice::InitOnCallerThread() {
338 message_loop_
= base::MessageLoop::current();
339 Queue(new AdbMessage(AdbMessage::kCommandCNXN
, kVersion
, kMaxPayload
,
340 kHostConnectMessage
));
344 net::StreamSocket
* AndroidUsbDevice::CreateSocket(const std::string
& command
) {
345 uint32 socket_id
= ++last_socket_id_
;
346 sockets_
[socket_id
] = new AndroidUsbSocket(this, socket_id
, command
,
347 base::Bind(&AndroidUsbDevice::SocketDeleted
, this));
348 return sockets_
[socket_id
];
351 void AndroidUsbDevice::Send(uint32 command
,
354 const std::string
& body
) {
355 scoped_refptr
<AdbMessage
> m
= new AdbMessage(command
, arg0
, arg1
, body
);
356 // Delay open request if not yet connected.
357 if (!is_connected_
) {
358 pending_messages_
.push_back(m
);
364 AndroidUsbDevice::~AndroidUsbDevice() {
366 usb_device_
->AddRef();
367 BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE
,
371 void AndroidUsbDevice::Queue(scoped_refptr
<AdbMessage
> message
) {
373 std::vector
<uint32
> header
;
374 header
.push_back(message
->command
);
375 header
.push_back(message
->arg0
);
376 header
.push_back(message
->arg1
);
377 bool append_zero
= true;
378 if (message
->body
.empty())
380 if (message
->command
== AdbMessage::kCommandAUTH
&&
381 message
->arg0
== AdbMessage::kAuthSignature
)
383 if (message
->command
== AdbMessage::kCommandWRTE
)
386 size_t body_length
= message
->body
.length() + (append_zero
? 1 : 0);
387 header
.push_back(body_length
);
388 header
.push_back(Checksum(message
->body
));
389 header
.push_back(message
->command
^ 0xffffffff);
390 scoped_refptr
<net::IOBuffer
> header_buffer
= new net::IOBuffer(kHeaderSize
);
391 memcpy(header_buffer
.get()->data(), &header
[0], kHeaderSize
);
392 outgoing_queue_
.push(std::make_pair(header_buffer
, kHeaderSize
));
395 if (!message
->body
.empty()) {
396 scoped_refptr
<net::IOBuffer
> body_buffer
= new net::IOBuffer(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(std::make_pair(body_buffer
, body_length
));
401 if (zero_mask_
&& (body_length
& zero_mask_
) == 0) {
402 // Send a zero length packet.
403 outgoing_queue_
.push(std::make_pair(body_buffer
, 0));
409 void AndroidUsbDevice::ProcessOutgoing() {
410 if (outgoing_queue_
.empty() || terminated_
)
413 BulkMessage message
= outgoing_queue_
.front();
414 outgoing_queue_
.pop();
415 DumpMessage(true, message
.first
->data(), message
.second
);
416 usb_device_
->BulkTransfer(USB_DIRECTION_OUTBOUND
, outbound_address_
,
417 message
.first
, message
.second
, kUsbTimeout
,
418 base::Bind(&AndroidUsbDevice::OutgoingMessageSent
, this));
421 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status
,
422 scoped_refptr
<net::IOBuffer
> buffer
,
424 if (status
!= USB_TRANSFER_COMPLETED
)
426 message_loop_
->PostTask(FROM_HERE
,
427 base::Bind(&AndroidUsbDevice::ProcessOutgoing
,
431 void AndroidUsbDevice::ReadHeader(bool initial
) {
434 if (!initial
&& HasOneRef())
435 return; // Stop polling.
436 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(kHeaderSize
);
437 usb_device_
->BulkTransfer(USB_DIRECTION_INBOUND
, inbound_address_
,
438 buffer
, kHeaderSize
, kUsbTimeout
,
439 base::Bind(&AndroidUsbDevice::ParseHeader
, this));
442 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status
,
443 scoped_refptr
<net::IOBuffer
> buffer
,
445 if (status
== USB_TRANSFER_TIMEOUT
) {
446 message_loop_
->PostTask(FROM_HERE
,
447 base::Bind(&AndroidUsbDevice::ReadHeader
, this,
452 if (status
!= USB_TRANSFER_COMPLETED
|| result
!= kHeaderSize
) {
453 TransferError(status
);
457 DumpMessage(false, buffer
->data(), result
);
458 std::vector
<uint32
> header(6);
459 memcpy(&header
[0], buffer
->data(), result
);
460 scoped_refptr
<AdbMessage
> message
=
461 new AdbMessage(header
[0], header
[1], header
[2], "");
462 uint32 data_length
= header
[3];
463 uint32 data_check
= header
[4];
464 uint32 magic
= header
[5];
465 if ((message
->command
^ 0xffffffff) != magic
) {
466 TransferError(USB_TRANSFER_ERROR
);
470 if (data_length
== 0) {
471 message_loop_
->PostTask(FROM_HERE
,
472 base::Bind(&AndroidUsbDevice::HandleIncoming
, this,
477 message_loop_
->PostTask(FROM_HERE
,
478 base::Bind(&AndroidUsbDevice::ReadBody
, this,
479 message
, data_length
, data_check
));
482 void AndroidUsbDevice::ReadBody(scoped_refptr
<AdbMessage
> message
,
485 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(data_length
);
486 usb_device_
->BulkTransfer(USB_DIRECTION_INBOUND
, inbound_address_
,
487 buffer
, data_length
, kUsbTimeout
,
488 base::Bind(&AndroidUsbDevice::ParseBody
, this, message
, data_length
,
492 void AndroidUsbDevice::ParseBody(scoped_refptr
<AdbMessage
> message
,
495 UsbTransferStatus status
,
496 scoped_refptr
<net::IOBuffer
> buffer
,
498 if (status
== USB_TRANSFER_TIMEOUT
) {
499 message_loop_
->PostTask(FROM_HERE
,
500 base::Bind(&AndroidUsbDevice::ReadBody
, this,
501 message
, data_length
, data_check
));
505 if (status
!= USB_TRANSFER_COMPLETED
||
506 static_cast<uint32
>(result
) != data_length
) {
507 TransferError(status
);
511 DumpMessage(false, buffer
->data(), data_length
);
512 message
->body
= std::string(buffer
->data(), result
);
513 if (Checksum(message
->body
) != data_check
) {
514 TransferError(USB_TRANSFER_ERROR
);
518 message_loop_
->PostTask(FROM_HERE
,
519 base::Bind(&AndroidUsbDevice::HandleIncoming
, this,
523 void AndroidUsbDevice::HandleIncoming(scoped_refptr
<AdbMessage
> message
) {
524 switch (message
->command
) {
525 case AdbMessage::kCommandAUTH
:
527 DCHECK_EQ(message
->arg0
, static_cast<uint32
>(AdbMessage::kAuthToken
));
528 if (signature_sent_
) {
529 Queue(new AdbMessage(AdbMessage::kCommandAUTH
,
530 AdbMessage::kAuthRSAPublicKey
, 0,
531 AndroidRSAPublicKey(rsa_key_
.get())));
533 signature_sent_
= true;
534 std::string signature
= AndroidRSASign(rsa_key_
.get(), message
->body
);
535 if (!signature
.empty()) {
536 Queue(new AdbMessage(AdbMessage::kCommandAUTH
,
537 AdbMessage::kAuthSignature
, 0,
540 Queue(new AdbMessage(AdbMessage::kCommandAUTH
,
541 AdbMessage::kAuthRSAPublicKey
, 0,
542 AndroidRSAPublicKey(rsa_key_
.get())));
547 case AdbMessage::kCommandCNXN
:
549 is_connected_
= true;
550 PendingMessages pending
;
551 pending
.swap(pending_messages_
);
552 for (PendingMessages::iterator it
= pending
.begin();
553 it
!= pending
.end(); ++it
) {
558 case AdbMessage::kCommandOKAY
:
559 case AdbMessage::kCommandWRTE
:
560 case AdbMessage::kCommandCLSE
:
562 AndroidUsbSockets::iterator it
= sockets_
.find(message
->arg1
);
563 if (it
!= sockets_
.end())
564 it
->second
->HandleIncoming(message
);
573 void AndroidUsbDevice::TransferError(UsbTransferStatus status
) {
574 message_loop_
->PostTask(FROM_HERE
,
575 base::Bind(&AndroidUsbDevice::Terminate
,
579 void AndroidUsbDevice::Terminate() {
585 // Iterate over copy.
586 AndroidUsbSockets
sockets(sockets_
);
587 for (AndroidUsbSockets::iterator it
= sockets
.begin();
588 it
!= sockets
.end(); ++it
) {
589 it
->second
->Terminated();
592 BrowserThread::PostTask(
593 BrowserThread::FILE, FROM_HERE
,
594 base::Bind(&ReleaseInterface
, usb_device_
));
597 void AndroidUsbDevice::SocketDeleted(uint32 socket_id
) {
598 sockets_
.erase(socket_id
);