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.
4
5 #include "chrome/browser/devtools/adb/android_usb_device.h"
6
7 #include <set>
8
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"
26
27 namespace {
28
29 const size_t kHeaderSize = 24;
30
31 const int kAdbClass = 0xff;
32 const int kAdbSubclass = 0x42;
33 const int kAdbProtocol = 0x1;
34
35 const int kUsbTimeout = 0;
36
37 const uint32 kMaxPayload = 4096;
38 const uint32 kVersion = 0x01000000;
39
40 static const char kHostConnectMessage[] = "host::";
41
42 using content::BrowserThread;
43
44 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
45 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet;
46
47 base::LazyInstance<AndroidUsbDevices>::Leaky g_devices =
48 LAZY_INSTANCE_INITIALIZER;
49
IsAndroidInterface(scoped_refptr<const UsbInterfaceDescriptor> interface)50 bool IsAndroidInterface(
51 scoped_refptr<const UsbInterfaceDescriptor> interface) {
52 if (interface->GetNumAltSettings() == 0)
53 return false;
54
55 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc =
56 interface->GetAltSetting(0);
57
58 if (idesc->GetInterfaceClass() != kAdbClass ||
59 idesc->GetInterfaceSubclass() != kAdbSubclass ||
60 idesc->GetInterfaceProtocol() != kAdbProtocol ||
61 idesc->GetNumEndpoints() != 2) {
62 return false;
63 }
64 return true;
65 }
66
ClaimInterface(crypto::RSAPrivateKey * rsa_key,scoped_refptr<UsbDeviceHandle> usb_handle,scoped_refptr<const UsbInterfaceDescriptor> interface,int interface_id)67 scoped_refptr<AndroidUsbDevice> ClaimInterface(
68 crypto::RSAPrivateKey* rsa_key,
69 scoped_refptr<UsbDeviceHandle> usb_handle,
70 scoped_refptr<const UsbInterfaceDescriptor> interface,
71 int interface_id) {
72 scoped_refptr<const UsbInterfaceAltSettingDescriptor> idesc =
73 interface->GetAltSetting(0);
74
75 int inbound_address = 0;
76 int outbound_address = 0;
77 int zero_mask = 0;
78
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)
83 continue;
84 if (edesc->GetDirection() == USB_DIRECTION_INBOUND)
85 inbound_address = edesc->GetAddress();
86 else
87 outbound_address = edesc->GetAddress();
88 zero_mask = edesc->GetMaximumPacketSize() - 1;
89 }
90
91 if (inbound_address == 0 || outbound_address == 0)
92 return NULL;
93
94 if (!usb_handle->ClaimInterface(interface_id))
95 return NULL;
96
97 base::string16 serial;
98 if (!usb_handle->GetSerial(&serial) || serial.empty())
99 return NULL;
100
101 return new AndroidUsbDevice(rsa_key, usb_handle, UTF16ToASCII(serial),
102 inbound_address, outbound_address, zero_mask);
103 }
104
Checksum(const std::string & data)105 uint32 Checksum(const std::string& data) {
106 unsigned char* x = (unsigned char*)data.data();
107 int count = data.length();
108 uint32 sum = 0;
109 while (count-- > 0)
110 sum += *x++;
111 return sum;
112 }
113
DumpMessage(bool outgoing,const char * data,size_t length)114 void DumpMessage(bool outgoing, const char* data, size_t length) {
115 #if 0
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)
122 result += " ";
123 }
124 for (size_t i = 0; i < 24; ++i) {
125 if (data[i] >= 0x20 && data[i] <= 0x7E)
126 result += data[i];
127 else
128 result += ".";
129 }
130 } else {
131 result = base::StringPrintf("%d: ", (int)length);
132 for (size_t i = 0; i < length; ++i) {
133 if (data[i] >= 0x20 && data[i] <= 0x7E)
134 result += data[i];
135 else
136 result += ".";
137 }
138 }
139 LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result;
140 #endif // 0
141 }
142
ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device)143 void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device) {
144 usb_device->ReleaseInterface(1);
145 usb_device->Close();
146 }
147
148 } // namespace
149
AdbMessage(uint32 command,uint32 arg0,uint32 arg1,const std::string & body)150 AdbMessage::AdbMessage(uint32 command,
151 uint32 arg0,
152 uint32 arg1,
153 const std::string& body)
154 : command(command),
155 arg0(arg0),
156 arg1(arg1),
157 body(body) {
158 }
159
~AdbMessage()160 AdbMessage::~AdbMessage() {
161 }
162
RespondWithCountOnUIThread(base::Callback<void (int)> callback,int count)163 static void RespondWithCountOnUIThread(base::Callback<void(int)> callback,
164 int count) {
165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
166 callback.Run(count);
167 }
168
RespondOnUIThread(const AndroidUsbDevicesCallback & callback,const AndroidUsbDevices & devices)169 static void RespondOnUIThread(const AndroidUsbDevicesCallback& callback,
170 const AndroidUsbDevices& devices) {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
172 callback.Run(devices);
173 }
174
RespondOnFileThread(const AndroidUsbDevicesCallback & callback)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()));
181 }
182
OpenAndroidDevicesOnFileThread(crypto::RSAPrivateKey * rsa_key,const base::Closure & barrier,scoped_refptr<UsbDevice> device,int interface_id,bool success)183 static void OpenAndroidDevicesOnFileThread(
184 crypto::RSAPrivateKey* rsa_key,
185 const base::Closure& barrier,
186 scoped_refptr<UsbDevice> device,
187 int interface_id,
188 bool success) {
189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
190 if (success) {
191 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces();
192 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open();
193 if (usb_handle) {
194 scoped_refptr<AndroidUsbDevice> device =
195 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id),
196 interface_id);
197 if (device.get())
198 g_devices.Get().push_back(device);
199 else
200 usb_handle->Close();
201 }
202 }
203 barrier.Run();
204 }
205
CountOnFileThread(const base::Callback<void (int)> & callback)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();
213 ++it) {
214 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces();
215 if (!config)
216 continue;
217
218 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
219 if (IsAndroidInterface(config->GetInterface(j)))
220 ++device_count;
221 }
222 }
223 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
224 base::Bind(&RespondWithCountOnUIThread, callback,
225 device_count));
226 }
227
EnumerateOnFileThread(crypto::RSAPrivateKey * rsa_key,const AndroidUsbDevicesCallback & callback)228 static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key,
229 const AndroidUsbDevicesCallback& callback) {
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
231
232 UsbService* service = UsbService::GetInstance();
233 UsbDevices usb_devices;
234 service->GetDevices(&usb_devices);
235
236 AndroidUsbDevices& devices = g_devices.Get();
237
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()) {
248 found_device = true;
249 claimed_devices.insert(usb_device);
250 }
251 }
252
253 if (!found_device)
254 it = devices.erase(it);
255 else
256 ++it;
257 }
258
259 // Add new devices.
260 base::Closure barrier = base::BarrierClosure(
261 usb_devices.size(), base::Bind(&RespondOnFileThread, callback));
262
263 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
264 ++it) {
265 if (ContainsKey(claimed_devices, it->get())) {
266 barrier.Run();
267 continue;
268 }
269
270 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces();
271 if (!config) {
272 barrier.Run();
273 continue;
274 }
275
276 bool has_android_interface = false;
277 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
278 if (!IsAndroidInterface(config->GetInterface(j)))
279 continue;
280
281 // Request permission on Chrome OS.
282 #if defined(OS_CHROMEOS)
283 (*it)->RequestUsbAcess(j, base::Bind(&OpenAndroidDevicesOnFileThread,
284 rsa_key, barrier, *it, j));
285 #else
286 OpenAndroidDevicesOnFileThread(rsa_key, barrier, *it, j, true);
287 #endif // defined(OS_CHROMEOS)
288
289 has_android_interface = true;
290 break;
291 }
292 if (!has_android_interface)
293 barrier.Run();
294 }
295 }
296
297 // static
CountDevices(const base::Callback<void (int)> & callback)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));
303 }
304
305 // static
Enumerate(crypto::RSAPrivateKey * rsa_key,const AndroidUsbDevicesCallback & 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,
311 callback));
312 }
313
AndroidUsbDevice(crypto::RSAPrivateKey * rsa_key,scoped_refptr<UsbDeviceHandle> usb_device,const std::string & serial,int inbound_address,int outbound_address,int zero_mask)314 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
315 scoped_refptr<UsbDeviceHandle> usb_device,
316 const std::string& serial,
317 int inbound_address,
318 int outbound_address,
319 int zero_mask)
320 : message_loop_(NULL),
321 rsa_key_(rsa_key->Copy()),
322 usb_device_(usb_device),
323 serial_(serial),
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),
330 terminated_(false) {
331 }
332
InitOnCallerThread()333 void AndroidUsbDevice::InitOnCallerThread() {
334 if (message_loop_)
335 return;
336 message_loop_ = base::MessageLoop::current();
337 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
338 kHostConnectMessage));
339 ReadHeader(true);
340 }
341
CreateSocket(const std::string & command)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];
347 }
348
Send(uint32 command,uint32 arg0,uint32 arg1,const std::string & body)349 void AndroidUsbDevice::Send(uint32 command,
350 uint32 arg0,
351 uint32 arg1,
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);
357 return;
358 }
359 Queue(m);
360 }
361
~AndroidUsbDevice()362 AndroidUsbDevice::~AndroidUsbDevice() {
363 Terminate();
364 usb_device_->AddRef();
365 BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE,
366 usb_device_.get());
367 }
368
Queue(scoped_refptr<AdbMessage> message)369 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
370 // Queue header.
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())
377 append_zero = false;
378 if (message->command == AdbMessage::kCommandAUTH &&
379 message->arg0 == AdbMessage::kAuthSignature)
380 append_zero = false;
381 if (message->command == AdbMessage::kCommandWRTE)
382 append_zero = false;
383
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));
391
392 // Queue body.
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());
396 if (append_zero)
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));
402 }
403 }
404 ProcessOutgoing();
405 }
406
ProcessOutgoing()407 void AndroidUsbDevice::ProcessOutgoing() {
408 if (outgoing_queue_.empty() || terminated_)
409 return;
410
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));
417 }
418
OutgoingMessageSent(UsbTransferStatus status,scoped_refptr<net::IOBuffer> buffer,size_t result)419 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status,
420 scoped_refptr<net::IOBuffer> buffer,
421 size_t result) {
422 if (status != USB_TRANSFER_COMPLETED)
423 return;
424 message_loop_->PostTask(FROM_HERE,
425 base::Bind(&AndroidUsbDevice::ProcessOutgoing,
426 this));
427 }
428
ReadHeader(bool initial)429 void AndroidUsbDevice::ReadHeader(bool initial) {
430 if (terminated_)
431 return;
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));
438 }
439
ParseHeader(UsbTransferStatus status,scoped_refptr<net::IOBuffer> buffer,size_t result)440 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
441 scoped_refptr<net::IOBuffer> buffer,
442 size_t result) {
443 if (status == USB_TRANSFER_TIMEOUT) {
444 message_loop_->PostTask(FROM_HERE,
445 base::Bind(&AndroidUsbDevice::ReadHeader, this,
446 false));
447 return;
448 }
449
450 if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) {
451 TransferError(status);
452 return;
453 }
454
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);
465 return;
466 }
467
468 if (data_length == 0) {
469 message_loop_->PostTask(FROM_HERE,
470 base::Bind(&AndroidUsbDevice::HandleIncoming, this,
471 message));
472 return;
473 }
474
475 message_loop_->PostTask(FROM_HERE,
476 base::Bind(&AndroidUsbDevice::ReadBody, this,
477 message, data_length, data_check));
478 }
479
ReadBody(scoped_refptr<AdbMessage> message,uint32 data_length,uint32 data_check)480 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message,
481 uint32 data_length,
482 uint32 data_check) {
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,
487 data_check));
488 }
489
ParseBody(scoped_refptr<AdbMessage> message,uint32 data_length,uint32 data_check,UsbTransferStatus status,scoped_refptr<net::IOBuffer> buffer,size_t result)490 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message,
491 uint32 data_length,
492 uint32 data_check,
493 UsbTransferStatus status,
494 scoped_refptr<net::IOBuffer> buffer,
495 size_t result) {
496 if (status == USB_TRANSFER_TIMEOUT) {
497 message_loop_->PostTask(FROM_HERE,
498 base::Bind(&AndroidUsbDevice::ReadBody, this,
499 message, data_length, data_check));
500 return;
501 }
502
503 if (status != USB_TRANSFER_COMPLETED ||
504 static_cast<uint32>(result) != data_length) {
505 TransferError(status);
506 return;
507 }
508
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);
513 return;
514 }
515
516 message_loop_->PostTask(FROM_HERE,
517 base::Bind(&AndroidUsbDevice::HandleIncoming, this,
518 message));
519 }
520
HandleIncoming(scoped_refptr<AdbMessage> message)521 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
522 switch (message->command) {
523 case AdbMessage::kCommandAUTH:
524 {
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())));
530 } else {
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,
536 signature));
537 } else {
538 Queue(new AdbMessage(AdbMessage::kCommandAUTH,
539 AdbMessage::kAuthRSAPublicKey, 0,
540 AndroidRSAPublicKey(rsa_key_.get())));
541 }
542 }
543 }
544 break;
545 case AdbMessage::kCommandCNXN:
546 {
547 is_connected_ = true;
548 PendingMessages pending;
549 pending.swap(pending_messages_);
550 for (PendingMessages::iterator it = pending.begin();
551 it != pending.end(); ++it) {
552 Queue(*it);
553 }
554 }
555 break;
556 case AdbMessage::kCommandOKAY:
557 case AdbMessage::kCommandWRTE:
558 case AdbMessage::kCommandCLSE:
559 {
560 AndroidUsbSockets::iterator it = sockets_.find(message->arg1);
561 if (it != sockets_.end())
562 it->second->HandleIncoming(message);
563 }
564 break;
565 default:
566 break;
567 }
568 ReadHeader(false);
569 }
570
TransferError(UsbTransferStatus status)571 void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
572 message_loop_->PostTask(FROM_HERE,
573 base::Bind(&AndroidUsbDevice::Terminate,
574 this));
575 }
576
Terminate()577 void AndroidUsbDevice::Terminate() {
578 if (terminated_)
579 return;
580
581 terminated_ = true;
582
583 // Iterate over copy.
584 AndroidUsbSockets sockets(sockets_);
585 for (AndroidUsbSockets::iterator it = sockets.begin();
586 it != sockets.end(); ++it) {
587 it->second->Terminated();
588 }
589
590 BrowserThread::PostTask(
591 BrowserThread::FILE, FROM_HERE,
592 base::Bind(&ReleaseInterface, usb_device_));
593 }
594
SocketDeleted(uint32 socket_id)595 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
596 sockets_.erase(socket_id);
597 }
598