Home | History | Annotate | Download | only in adb
      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 
     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 
     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 
    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 
    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 
    143 void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device) {
    144   usb_device->ReleaseInterface(1);
    145   usb_device->Close();
    146 }
    147 
    148 }  // namespace
    149 
    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 
    160 AdbMessage::~AdbMessage() {
    161 }
    162 
    163 static void RespondWithCountOnUIThread(base::Callback<void(int)> callback,
    164                                        int count) {
    165   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    166   callback.Run(count);
    167 }
    168 
    169 static void RespondOnUIThread(const AndroidUsbDevicesCallback& callback,
    170                               const AndroidUsbDevices& devices) {
    171   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    172   callback.Run(devices);
    173 }
    174 
    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 
    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 
    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 
    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
    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
    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 
    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 
    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 
    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 
    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 
    362 AndroidUsbDevice::~AndroidUsbDevice() {
    363   Terminate();
    364   usb_device_->AddRef();
    365   BrowserThread::ReleaseSoon(BrowserThread::FILE, FROM_HERE,
    366                              usb_device_.get());
    367 }
    368 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    571 void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
    572   message_loop_->PostTask(FROM_HERE,
    573                           base::Bind(&AndroidUsbDevice::Terminate,
    574                                      this));
    575 }
    576 
    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 
    595 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
    596   sockets_.erase(socket_id);
    597 }
    598