Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / devtools / device / usb / android_usb_device.cc
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.
4
5 #include "chrome/browser/devtools/device/usb/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 "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"
28
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;
36
37 namespace {
38
39 const size_t kHeaderSize = 24;
40
41 const int kAdbClass = 0xff;
42 const int kAdbSubclass = 0x42;
43 const int kAdbProtocol = 0x1;
44
45 const int kUsbTimeout = 0;
46
47 const uint32 kMaxPayload = 4096;
48 const uint32 kVersion = 0x01000000;
49
50 static const char kHostConnectMessage[] = "host::";
51
52 using content::BrowserThread;
53
54 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
55 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet;
56
57 // Stores android wrappers around claimed usb devices on caller thread.
58 base::LazyInstance<std::vector<AndroidUsbDevice*> >::Leaky g_devices =
59     LAZY_INSTANCE_INITIALIZER;
60
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) {
67     return false;
68   }
69   return true;
70 }
71
72 scoped_refptr<AndroidUsbDevice> ClaimInterface(
73     crypto::RSAPrivateKey* rsa_key,
74     scoped_refptr<UsbDeviceHandle> usb_handle,
75     const UsbInterfaceDescriptor& interface) {
76   int inbound_address = 0;
77   int outbound_address = 0;
78   int zero_mask = 0;
79
80   for (UsbEndpointDescriptor::Iterator endpointIt = interface.endpoints.begin();
81        endpointIt != interface.endpoints.end();
82        ++endpointIt) {
83     if (endpointIt->transfer_type != device::USB_TRANSFER_BULK)
84       continue;
85     if (endpointIt->direction == device::USB_DIRECTION_INBOUND)
86       inbound_address = endpointIt->address;
87     else
88       outbound_address = endpointIt->address;
89     zero_mask = endpointIt->maximum_packet_size - 1;
90   }
91
92   if (inbound_address == 0 || outbound_address == 0)
93     return NULL;
94
95   if (!usb_handle->ClaimInterface(interface.interface_number))
96     return NULL;
97
98   base::string16 serial;
99   if (!usb_handle->GetDevice()->GetSerialNumber(&serial) || serial.empty())
100     return NULL;
101
102   return new AndroidUsbDevice(rsa_key,
103                               usb_handle,
104                               base::UTF16ToASCII(serial),
105                               inbound_address,
106                               outbound_address,
107                               zero_mask,
108                               interface.interface_number);
109 }
110
111 uint32 Checksum(const std::string& data) {
112   unsigned char* x = (unsigned char*)data.data();
113   int count = data.length();
114   uint32 sum = 0;
115   while (count-- > 0)
116     sum += *x++;
117   return sum;
118 }
119
120 void DumpMessage(bool outgoing, const char* data, size_t length) {
121 #if 0
122   std::string result = "";
123   if (length == kHeaderSize) {
124     for (size_t i = 0; i < 24; ++i) {
125       result += base::StringPrintf("%02x",
126           data[i] > 0 ? data[i] : (data[i] + 0x100) & 0xFF);
127       if ((i + 1) % 4 == 0)
128         result += " ";
129     }
130     for (size_t i = 0; i < 24; ++i) {
131       if (data[i] >= 0x20 && data[i] <= 0x7E)
132         result += data[i];
133       else
134         result += ".";
135     }
136   } else {
137     result = base::StringPrintf("%d: ", (int)length);
138     for (size_t i = 0; i < length; ++i) {
139       if (data[i] >= 0x20 && data[i] <= 0x7E)
140         result += data[i];
141       else
142         result += ".";
143     }
144   }
145   LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result;
146 #endif  // 0
147 }
148
149 void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device,
150                       int interface_id) {
151   usb_device->ReleaseInterface(interface_id);
152   usb_device->Close();
153 }
154
155 }  // namespace
156
157 AdbMessage::AdbMessage(uint32 command,
158                        uint32 arg0,
159                        uint32 arg1,
160                        const std::string& body)
161     : command(command),
162       arg0(arg0),
163       arg1(arg1),
164       body(body) {
165 }
166
167 AdbMessage::~AdbMessage() {
168 }
169
170 static void RespondOnCallerThread(const AndroidUsbDevicesCallback& callback,
171                                   AndroidUsbDevices* new_devices) {
172   scoped_ptr<AndroidUsbDevices> devices(new_devices);
173
174   // Add raw pointers to the newly claimed devices.
175   for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end();
176        ++it) {
177     g_devices.Get().push_back(it->get());
178   }
179
180   // Return all claimed devices.
181   AndroidUsbDevices result(g_devices.Get().begin(), g_devices.Get().end());
182   callback.Run(result);
183 }
184
185 static void RespondOnFileThread(
186     const AndroidUsbDevicesCallback& callback,
187     AndroidUsbDevices* devices,
188     scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) {
189   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
190   caller_message_loop_proxy->PostTask(
191       FROM_HERE,
192       base::Bind(&RespondOnCallerThread, callback, devices));
193 }
194
195 static void OpenAndroidDeviceOnFileThread(
196     AndroidUsbDevices* devices,
197     crypto::RSAPrivateKey* rsa_key,
198     const base::Closure& barrier,
199     scoped_refptr<UsbDevice> device,
200     int interface_id,
201     bool success) {
202   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
203   if (success) {
204     const UsbConfigDescriptor& config = device->GetConfiguration();
205     scoped_refptr<UsbDeviceHandle> usb_handle = device->Open();
206     if (usb_handle.get()) {
207       scoped_refptr<AndroidUsbDevice> android_device =
208           ClaimInterface(rsa_key, usb_handle, config.interfaces[interface_id]);
209       if (android_device.get())
210         devices->push_back(android_device.get());
211       else
212         usb_handle->Close();
213     }
214   }
215   barrier.Run();
216 }
217
218 static int CountOnFileThread() {
219   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
220   UsbService* service = device::DeviceClient::Get()->GetUsbService();
221   UsbDevices usb_devices;
222   if (service != NULL)
223     service->GetDevices(&usb_devices);
224   int device_count = 0;
225   for (UsbDevices::iterator deviceIt = usb_devices.begin();
226        deviceIt != usb_devices.end();
227        ++deviceIt) {
228     const UsbConfigDescriptor& config = (*deviceIt)->GetConfiguration();
229
230     for (UsbInterfaceDescriptor::Iterator ifaceIt = config.interfaces.begin();
231          ifaceIt != config.interfaces.end();
232          ++ifaceIt) {
233       if (IsAndroidInterface(*ifaceIt)) {
234         ++device_count;
235       }
236     }
237   }
238   return device_count;
239 }
240
241 static void EnumerateOnFileThread(
242     crypto::RSAPrivateKey* rsa_key,
243     const AndroidUsbDevicesCallback& callback,
244     scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) {
245   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
246
247   UsbService* service = device::DeviceClient::Get()->GetUsbService();
248   UsbDevices usb_devices;
249   if (service != NULL)
250     service->GetDevices(&usb_devices);
251
252   // Add new devices.
253   AndroidUsbDevices* devices = new AndroidUsbDevices();
254   base::Closure barrier = base::BarrierClosure(
255       usb_devices.size(), base::Bind(&RespondOnFileThread,
256                                      callback,
257                                      devices,
258                                      caller_message_loop_proxy));
259
260   for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
261        ++it) {
262     const UsbConfigDescriptor& config = (*it)->GetConfiguration();
263
264     bool has_android_interface = false;
265     for (size_t j = 0; j < config.interfaces.size(); ++j) {
266       if (!IsAndroidInterface(config.interfaces[j])) {
267         continue;
268       }
269
270       // Request permission on Chrome OS.
271 #if defined(OS_CHROMEOS)
272       (*it)->RequestUsbAccess(j, base::Bind(&OpenAndroidDeviceOnFileThread,
273                                             devices, rsa_key, barrier, *it, j));
274 #else
275       OpenAndroidDeviceOnFileThread(devices, rsa_key, barrier, *it, j, true);
276 #endif  // defined(OS_CHROMEOS)
277
278       has_android_interface = true;
279       break;
280     }
281     if (!has_android_interface)
282       barrier.Run();
283   }
284 }
285
286 // static
287 void AndroidUsbDevice::CountDevices(
288     const base::Callback<void(int)>& callback) {
289   BrowserThread::PostTaskAndReplyWithResult(
290       BrowserThread::FILE,
291       FROM_HERE,
292       base::Bind(&CountOnFileThread),
293       callback);
294 }
295
296 // static
297 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key,
298                                  const AndroidUsbDevicesCallback& callback) {
299
300   // Collect devices with closed handles.
301   for (std::vector<AndroidUsbDevice*>::iterator it = g_devices.Get().begin();
302        it != g_devices.Get().end(); ++it) {
303     if ((*it)->usb_handle_.get()) {
304       BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
305           base::Bind(&AndroidUsbDevice::TerminateIfReleased, *it,
306                      (*it)->usb_handle_));
307     }
308   }
309
310   // Then look for the new devices.
311   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
312                           base::Bind(&EnumerateOnFileThread, rsa_key, callback,
313                                      base::MessageLoopProxy::current()));
314 }
315
316 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
317                                    scoped_refptr<UsbDeviceHandle> usb_device,
318                                    const std::string& serial,
319                                    int inbound_address,
320                                    int outbound_address,
321                                    int zero_mask,
322                                    int interface_id)
323     : message_loop_(NULL),
324       rsa_key_(rsa_key->Copy()),
325       usb_handle_(usb_device),
326       serial_(serial),
327       inbound_address_(inbound_address),
328       outbound_address_(outbound_address),
329       zero_mask_(zero_mask),
330       interface_id_(interface_id),
331       is_connected_(false),
332       signature_sent_(false),
333       last_socket_id_(256),
334       weak_factory_(this) {
335 }
336
337 void AndroidUsbDevice::InitOnCallerThread() {
338   if (message_loop_)
339     return;
340   message_loop_ = base::MessageLoop::current();
341   Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
342                        kHostConnectMessage));
343   ReadHeader();
344 }
345
346 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) {
347   if (!usb_handle_.get())
348     return NULL;
349
350   uint32 socket_id = ++last_socket_id_;
351   sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command,
352       base::Bind(&AndroidUsbDevice::SocketDeleted, this));
353   return sockets_[socket_id];
354 }
355
356 void AndroidUsbDevice::Send(uint32 command,
357                             uint32 arg0,
358                             uint32 arg1,
359                             const std::string& body) {
360   scoped_refptr<AdbMessage> m = new AdbMessage(command, arg0, arg1, body);
361   // Delay open request if not yet connected.
362   if (!is_connected_) {
363     pending_messages_.push_back(m);
364     return;
365   }
366   Queue(m);
367 }
368
369 AndroidUsbDevice::~AndroidUsbDevice() {
370   DCHECK(message_loop_ == base::MessageLoop::current());
371   Terminate();
372 }
373
374 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
375   DCHECK(message_loop_ == base::MessageLoop::current());
376
377   // Queue header.
378   std::vector<uint32> header;
379   header.push_back(message->command);
380   header.push_back(message->arg0);
381   header.push_back(message->arg1);
382   bool append_zero = true;
383   if (message->body.empty())
384     append_zero = false;
385   if (message->command == AdbMessage::kCommandAUTH &&
386       message->arg0 == AdbMessage::kAuthSignature)
387     append_zero = false;
388   if (message->command == AdbMessage::kCommandWRTE)
389     append_zero = false;
390
391   size_t body_length = message->body.length() + (append_zero ? 1 : 0);
392   header.push_back(body_length);
393   header.push_back(Checksum(message->body));
394   header.push_back(message->command ^ 0xffffffff);
395   scoped_refptr<net::IOBufferWithSize> header_buffer =
396       new net::IOBufferWithSize(kHeaderSize);
397   memcpy(header_buffer.get()->data(), &header[0], kHeaderSize);
398   outgoing_queue_.push(header_buffer);
399
400   // Queue body.
401   if (!message->body.empty()) {
402     scoped_refptr<net::IOBufferWithSize> body_buffer =
403         new net::IOBufferWithSize(body_length);
404     memcpy(body_buffer->data(), message->body.data(), message->body.length());
405     if (append_zero)
406       body_buffer->data()[body_length - 1] = 0;
407     outgoing_queue_.push(body_buffer);
408     if (zero_mask_ && (body_length & zero_mask_) == 0) {
409       // Send a zero length packet.
410       outgoing_queue_.push(new net::IOBufferWithSize(0));
411     }
412   }
413   ProcessOutgoing();
414 }
415
416 void AndroidUsbDevice::ProcessOutgoing() {
417   DCHECK(message_loop_ == base::MessageLoop::current());
418
419   if (outgoing_queue_.empty() || !usb_handle_.get())
420     return;
421
422   BulkMessage message = outgoing_queue_.front();
423   outgoing_queue_.pop();
424   DumpMessage(true, message->data(), message->size());
425   usb_handle_->BulkTransfer(device::USB_DIRECTION_OUTBOUND,
426                             outbound_address_,
427                             message.get(),
428                             message->size(),
429                             kUsbTimeout,
430                             base::Bind(&AndroidUsbDevice::OutgoingMessageSent,
431                                        weak_factory_.GetWeakPtr()));
432 }
433
434 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status,
435                                            scoped_refptr<net::IOBuffer> buffer,
436                                            size_t result) {
437   DCHECK(message_loop_ == base::MessageLoop::current());
438
439   if (status != device::USB_TRANSFER_COMPLETED)
440     return;
441   message_loop_->PostTask(FROM_HERE,
442                           base::Bind(&AndroidUsbDevice::ProcessOutgoing, this));
443 }
444
445 void AndroidUsbDevice::ReadHeader() {
446   DCHECK(message_loop_ == base::MessageLoop::current());
447
448   if (!usb_handle_.get())
449     return;
450   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize);
451   usb_handle_->BulkTransfer(
452       device::USB_DIRECTION_INBOUND,
453       inbound_address_,
454       buffer.get(),
455       kHeaderSize,
456       kUsbTimeout,
457       base::Bind(&AndroidUsbDevice::ParseHeader, weak_factory_.GetWeakPtr()));
458 }
459
460 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
461                                    scoped_refptr<net::IOBuffer> buffer,
462                                    size_t result) {
463   DCHECK(message_loop_ == base::MessageLoop::current());
464
465   if (status == device::USB_TRANSFER_TIMEOUT) {
466     message_loop_->PostTask(FROM_HERE,
467                             base::Bind(&AndroidUsbDevice::ReadHeader, this));
468     return;
469   }
470
471   if (status != device::USB_TRANSFER_COMPLETED || result != kHeaderSize) {
472     TransferError(status);
473     return;
474   }
475
476   DumpMessage(false, buffer->data(), result);
477   std::vector<uint32> header(6);
478   memcpy(&header[0], buffer->data(), result);
479   scoped_refptr<AdbMessage> message =
480       new AdbMessage(header[0], header[1], header[2], "");
481   uint32 data_length = header[3];
482   uint32 data_check = header[4];
483   uint32 magic = header[5];
484   if ((message->command ^ 0xffffffff) != magic) {
485     TransferError(device::USB_TRANSFER_ERROR);
486     return;
487   }
488
489   if (data_length == 0) {
490     message_loop_->PostTask(FROM_HERE,
491                             base::Bind(&AndroidUsbDevice::HandleIncoming, this,
492                                        message));
493     return;
494   }
495
496   message_loop_->PostTask(FROM_HERE,
497                           base::Bind(&AndroidUsbDevice::ReadBody, this,
498                                      message, data_length, data_check));
499 }
500
501 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message,
502                                 uint32 data_length,
503                                 uint32 data_check) {
504   DCHECK(message_loop_ == base::MessageLoop::current());
505
506   if (!usb_handle_.get())
507     return;
508   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length);
509   usb_handle_->BulkTransfer(device::USB_DIRECTION_INBOUND,
510                             inbound_address_,
511                             buffer.get(),
512                             data_length,
513                             kUsbTimeout,
514                             base::Bind(&AndroidUsbDevice::ParseBody,
515                                        weak_factory_.GetWeakPtr(),
516                                        message,
517                                        data_length,
518                                        data_check));
519 }
520
521 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message,
522                                  uint32 data_length,
523                                  uint32 data_check,
524                                  UsbTransferStatus status,
525                                  scoped_refptr<net::IOBuffer> buffer,
526                                  size_t result) {
527   DCHECK(message_loop_ == base::MessageLoop::current());
528
529   if (status == device::USB_TRANSFER_TIMEOUT) {
530     message_loop_->PostTask(FROM_HERE,
531                             base::Bind(&AndroidUsbDevice::ReadBody, this,
532                             message, data_length, data_check));
533     return;
534   }
535
536   if (status != device::USB_TRANSFER_COMPLETED ||
537       static_cast<uint32>(result) != data_length) {
538     TransferError(status);
539     return;
540   }
541
542   DumpMessage(false, buffer->data(), data_length);
543   message->body = std::string(buffer->data(), result);
544   if (Checksum(message->body) != data_check) {
545     TransferError(device::USB_TRANSFER_ERROR);
546     return;
547   }
548
549   message_loop_->PostTask(FROM_HERE,
550                           base::Bind(&AndroidUsbDevice::HandleIncoming, this,
551                                      message));
552 }
553
554 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
555   DCHECK(message_loop_ == base::MessageLoop::current());
556
557   switch (message->command) {
558     case AdbMessage::kCommandAUTH:
559       {
560         DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken));
561         if (signature_sent_) {
562           Queue(new AdbMessage(AdbMessage::kCommandAUTH,
563                                AdbMessage::kAuthRSAPublicKey, 0,
564                                AndroidRSAPublicKey(rsa_key_.get())));
565         } else {
566           signature_sent_ = true;
567           std::string signature = AndroidRSASign(rsa_key_.get(), message->body);
568           if (!signature.empty()) {
569             Queue(new AdbMessage(AdbMessage::kCommandAUTH,
570                                  AdbMessage::kAuthSignature, 0,
571                                  signature));
572           } else {
573             Queue(new AdbMessage(AdbMessage::kCommandAUTH,
574                                  AdbMessage::kAuthRSAPublicKey, 0,
575                                  AndroidRSAPublicKey(rsa_key_.get())));
576           }
577         }
578       }
579       break;
580     case AdbMessage::kCommandCNXN:
581       {
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(*it);
588         }
589       }
590       break;
591     case AdbMessage::kCommandOKAY:
592     case AdbMessage::kCommandWRTE:
593     case AdbMessage::kCommandCLSE:
594       {
595         AndroidUsbSockets::iterator it = sockets_.find(message->arg1);
596         if (it != sockets_.end())
597           it->second->HandleIncoming(message);
598       }
599       break;
600     default:
601       break;
602   }
603   ReadHeader();
604 }
605
606 void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
607   DCHECK(message_loop_ == base::MessageLoop::current());
608
609   message_loop_->PostTask(FROM_HERE,
610                           base::Bind(&AndroidUsbDevice::Terminate, this));
611 }
612
613 void AndroidUsbDevice::TerminateIfReleased(
614     scoped_refptr<UsbDeviceHandle> usb_handle) {
615   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
616   if (usb_handle->GetDevice().get())
617     return;
618   message_loop_->PostTask(FROM_HERE,
619                           base::Bind(&AndroidUsbDevice::Terminate, this));
620 }
621
622 void AndroidUsbDevice::Terminate() {
623   DCHECK(message_loop_ == base::MessageLoop::current());
624
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);
629
630   if (!usb_handle_.get())
631     return;
632
633   // Make sure we zero-out handle so that closing connections did not open
634   // new connections.
635   scoped_refptr<UsbDeviceHandle> usb_handle = usb_handle_;
636   usb_handle_ = NULL;
637
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);
643   }
644   DCHECK(sockets_.empty());
645
646   BrowserThread::PostTask(
647       BrowserThread::FILE, FROM_HERE,
648       base::Bind(&ReleaseInterface, usb_handle, interface_id_));
649 }
650
651 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
652   DCHECK(message_loop_ == base::MessageLoop::current());
653
654   sockets_.erase(socket_id);
655 }