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