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/base64.h"
     10 #include "base/lazy_instance.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/stl_util.h"
     13 #include "base/strings/string_util.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "chrome/browser/devtools/adb/android_rsa.h"
     16 #include "chrome/browser/devtools/adb/android_usb_socket.h"
     17 #include "chrome/browser/usb/usb_device.h"
     18 #include "chrome/browser/usb/usb_interface.h"
     19 #include "chrome/browser/usb/usb_service.h"
     20 #include "content/public/browser/browser_thread.h"
     21 #include "crypto/rsa_private_key.h"
     22 #include "net/base/ip_endpoint.h"
     23 #include "net/base/net_errors.h"
     24 #include "net/socket/stream_socket.h"
     25 
     26 namespace {
     27 
     28 const size_t kHeaderSize = 24;
     29 
     30 const int kAdbClass = 0xff;
     31 const int kAdbSubclass = 0x42;
     32 const int kAdbProtocol = 0x1;
     33 
     34 const int kUsbTimeout = 0;
     35 
     36 const uint32 kMaxPayload = 4096;
     37 const uint32 kVersion = 0x01000000;
     38 
     39 static const char kHostConnectMessage[] = "host::";
     40 
     41 using content::BrowserThread;
     42 
     43 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
     44 
     45 base::LazyInstance<AndroidUsbDevices>::Leaky g_devices =
     46     LAZY_INSTANCE_INITIALIZER;
     47 
     48 static scoped_refptr<AndroidUsbDevice> ClaimInterface(
     49     crypto::RSAPrivateKey* rsa_key,
     50     scoped_refptr<UsbDeviceHandle> usb_device,
     51     const UsbInterface* interface,
     52     int interface_id) {
     53   if (interface->GetNumAltSettings() == 0)
     54     return NULL;
     55 
     56   scoped_refptr<const UsbInterfaceDescriptor> idesc =
     57       interface->GetAltSetting(0).get();
     58 
     59   if (idesc->GetInterfaceClass() != kAdbClass ||
     60       idesc->GetInterfaceSubclass() != kAdbSubclass ||
     61       idesc->GetInterfaceProtocol() != kAdbProtocol ||
     62       idesc->GetNumEndpoints() != 2) {
     63     return NULL;
     64   }
     65 
     66   int inbound_address = 0;
     67   int outbound_address = 0;
     68   int zero_mask = 0;
     69 
     70   for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) {
     71     scoped_refptr<const UsbEndpointDescriptor> edesc =
     72         idesc->GetEndpoint(i).get();
     73     if (edesc->GetTransferType() != USB_TRANSFER_BULK)
     74       continue;
     75     if (edesc->GetDirection() == USB_DIRECTION_INBOUND)
     76       inbound_address = edesc->GetAddress();
     77     else
     78       outbound_address = edesc->GetAddress();
     79     zero_mask = edesc->GetMaximumPacketSize() - 1;
     80   }
     81 
     82   if (inbound_address == 0 || outbound_address == 0)
     83     return NULL;
     84 
     85   if (!usb_device->ClaimInterface(interface_id))
     86     return NULL;
     87 
     88   base::string16 serial;
     89   if (!usb_device->GetSerial(&serial) || serial.empty())
     90     return NULL;
     91 
     92   return new AndroidUsbDevice(rsa_key, usb_device, UTF16ToASCII(serial),
     93                               inbound_address, outbound_address, zero_mask);
     94 }
     95 
     96 static uint32 Checksum(const std::string& data) {
     97   unsigned char* x = (unsigned char*)data.data();
     98   int count = data.length();
     99   uint32 sum = 0;
    100   while (count-- > 0)
    101     sum += *x++;
    102   return sum;
    103 }
    104 
    105 static void DumpMessage(bool outgoing, const char* data, size_t length) {
    106 #if 0
    107   std::string result = "";
    108   if (length == kHeaderSize) {
    109     for (size_t i = 0; i < 24; ++i) {
    110       result += base::StringPrintf("%02x",
    111           data[i] > 0 ? data[i] : (data[i] + 0x100) & 0xFF);
    112       if ((i + 1) % 4 == 0)
    113         result += " ";
    114     }
    115     for (size_t i = 0; i < 24; ++i) {
    116       if (data[i] >= 0x20 && data[i] <= 0x7E)
    117         result += data[i];
    118       else
    119         result += ".";
    120     }
    121   } else {
    122     result = base::StringPrintf("%d: ", (int)length);
    123     for (size_t i = 0; i < length; ++i) {
    124       if (data[i] >= 0x20 && data[i] <= 0x7E)
    125         result += data[i];
    126       else
    127         result += ".";
    128     }
    129   }
    130   LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result;
    131 #endif  // 0
    132 }
    133 
    134 }  // namespace
    135 
    136 AdbMessage::AdbMessage(uint32 command,
    137                        uint32 arg0,
    138                        uint32 arg1,
    139                        const std::string& body)
    140     : command(command),
    141       arg0(arg0),
    142       arg1(arg1),
    143       body(body) {
    144 }
    145 
    146 AdbMessage::~AdbMessage() {
    147 }
    148 
    149 static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key,
    150                                   AndroidUsbDevices* result) {
    151   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    152 
    153   UsbService* service = UsbService::GetInstance();
    154   AndroidUsbDevices& devices = g_devices.Get();
    155 
    156   UsbDevices usb_devices;
    157   service->GetDevices(&usb_devices);
    158 
    159   // GC Android devices with no actual usb device.
    160   AndroidUsbDevices::iterator it = devices.begin();
    161   std::set<UsbDevice*> claimed_devices;
    162   while (it != devices.end()) {
    163     bool found_device = false;
    164     for (UsbDevices::iterator it2 = usb_devices.begin();
    165          it2 != usb_devices.end() && !found_device; ++it2) {
    166       UsbDevice* usb_device = it2->get();
    167       AndroidUsbDevice* device = it->get();
    168       if (usb_device == device->usb_device()->device()) {
    169         found_device = true;
    170         claimed_devices.insert(usb_device);
    171       }
    172     }
    173 
    174     if (!found_device)
    175       it = devices.erase(it);
    176     else
    177       ++it;
    178   }
    179 
    180   // Add new devices.
    181   for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
    182        ++it) {
    183     if (ContainsKey(claimed_devices, it->get()))
    184       continue;
    185 
    186     scoped_refptr<UsbConfigDescriptor> config = new UsbConfigDescriptor();
    187     bool success = (*it)->ListInterfaces(config.get());
    188     if (!success)
    189       continue;
    190 
    191     scoped_refptr<UsbDeviceHandle> usb_device = (*it)->Open();
    192     if (!usb_device)
    193       continue;
    194 
    195     bool claimed = false;
    196     for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
    197       scoped_refptr<AndroidUsbDevice> device =
    198           ClaimInterface(rsa_key, usb_device, config->GetInterface(j), j);
    199       if (device.get()) {
    200         devices.push_back(device);
    201         claimed = true;
    202       }
    203     }
    204     if (!claimed)
    205       usb_device->Close();
    206   }
    207 
    208   *result = devices;
    209 }
    210 
    211 static void InitDevicesOnCallerThread(
    212     AndroidUsbDevices* devices,
    213     const AndroidUsbDevicesCallback& callback) {
    214   for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end();
    215        ++it) {
    216     (*it)->InitOnCallerThread();
    217   }
    218   callback.Run(*devices);
    219   delete devices;
    220 }
    221 
    222 // static
    223 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key,
    224                                  const AndroidUsbDevicesCallback& callback) {
    225   AndroidUsbDevices* devices = new AndroidUsbDevices();
    226   BrowserThread::PostTaskAndReply(
    227       BrowserThread::FILE, FROM_HERE,
    228       base::Bind(&EnumerateOnFileThread, rsa_key, devices),
    229       base::Bind(&InitDevicesOnCallerThread, devices, callback));
    230 }
    231 
    232 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
    233                                    scoped_refptr<UsbDeviceHandle> usb_device,
    234                                    const std::string& serial,
    235                                    int inbound_address,
    236                                    int outbound_address,
    237                                    int zero_mask)
    238     : message_loop_(NULL),
    239       rsa_key_(rsa_key->Copy()),
    240       usb_device_(usb_device),
    241       serial_(serial),
    242       inbound_address_(inbound_address),
    243       outbound_address_(outbound_address),
    244       zero_mask_(zero_mask),
    245       is_connected_(false),
    246       signature_sent_(false),
    247       last_socket_id_(256),
    248       terminated_(false) {
    249 }
    250 
    251 void AndroidUsbDevice::InitOnCallerThread() {
    252   if (message_loop_)
    253     return;
    254   message_loop_ = base::MessageLoop::current();
    255   Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload,
    256                        kHostConnectMessage));
    257   ReadHeader(true);
    258 }
    259 
    260 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) {
    261   uint32 socket_id = ++last_socket_id_;
    262   sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command,
    263       base::Bind(&AndroidUsbDevice::SocketDeleted, this));
    264   return sockets_[socket_id];
    265 }
    266 
    267 void AndroidUsbDevice::Send(uint32 command,
    268                             uint32 arg0,
    269                             uint32 arg1,
    270                             const std::string& body) {
    271   scoped_refptr<AdbMessage> m = new AdbMessage(command, arg0, arg1, body);
    272   // Delay open request if not yet connected.
    273   if (!is_connected_) {
    274     pending_messages_.push_back(m);
    275     return;
    276   }
    277   Queue(m);
    278 }
    279 
    280 AndroidUsbDevice::~AndroidUsbDevice() {
    281   Terminate();
    282 }
    283 
    284 void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) {
    285   // Queue header.
    286   std::vector<uint32> header;
    287   header.push_back(message->command);
    288   header.push_back(message->arg0);
    289   header.push_back(message->arg1);
    290   bool append_zero = true;
    291   if (message->body.empty())
    292     append_zero = false;
    293   if (message->command == AdbMessage::kCommandAUTH &&
    294       message->arg0 == AdbMessage::kAuthSignature)
    295     append_zero = false;
    296   if (message->command == AdbMessage::kCommandWRTE)
    297     append_zero = false;
    298 
    299   size_t body_length = message->body.length() + (append_zero ? 1 : 0);
    300   header.push_back(body_length);
    301   header.push_back(Checksum(message->body));
    302   header.push_back(message->command ^ 0xffffffff);
    303   scoped_refptr<net::IOBuffer> header_buffer = new net::IOBuffer(kHeaderSize);
    304   memcpy(header_buffer.get()->data(), &header[0], kHeaderSize);
    305   outgoing_queue_.push(std::make_pair(header_buffer, kHeaderSize));
    306 
    307   // Queue body.
    308   if (!message->body.empty()) {
    309     scoped_refptr<net::IOBuffer> body_buffer = new net::IOBuffer(body_length);
    310     memcpy(body_buffer->data(), message->body.data(), message->body.length());
    311     if (append_zero)
    312       body_buffer->data()[body_length - 1] = 0;
    313     outgoing_queue_.push(std::make_pair(body_buffer, body_length));
    314     if (zero_mask_ && (body_length & zero_mask_) == 0) {
    315       // Send a zero length packet.
    316       outgoing_queue_.push(std::make_pair(body_buffer, 0));
    317     }
    318   }
    319   ProcessOutgoing();
    320 }
    321 
    322 void AndroidUsbDevice::ProcessOutgoing() {
    323   if (outgoing_queue_.empty() || terminated_)
    324     return;
    325 
    326   BulkMessage message = outgoing_queue_.front();
    327   outgoing_queue_.pop();
    328   DumpMessage(true, message.first->data(), message.second);
    329   usb_device_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_,
    330       message.first, message.second, kUsbTimeout,
    331       base::Bind(&AndroidUsbDevice::OutgoingMessageSent, this));
    332 }
    333 
    334 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status,
    335                                            scoped_refptr<net::IOBuffer> buffer,
    336                                            size_t result) {
    337   if (status != USB_TRANSFER_COMPLETED)
    338     return;
    339   message_loop_->PostTask(FROM_HERE,
    340                           base::Bind(&AndroidUsbDevice::ProcessOutgoing,
    341                                      this));
    342 }
    343 
    344 void AndroidUsbDevice::ReadHeader(bool initial) {
    345   if (terminated_)
    346     return;
    347   if (!initial && HasOneRef())
    348     return;  // Stop polling.
    349   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize);
    350   usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
    351       buffer, kHeaderSize, kUsbTimeout,
    352       base::Bind(&AndroidUsbDevice::ParseHeader, this));
    353 }
    354 
    355 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
    356                                    scoped_refptr<net::IOBuffer> buffer,
    357                                    size_t result) {
    358   if (status == USB_TRANSFER_TIMEOUT) {
    359     message_loop_->PostTask(FROM_HERE,
    360                             base::Bind(&AndroidUsbDevice::ReadHeader, this,
    361                                        false));
    362     return;
    363   }
    364 
    365   if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) {
    366     TransferError(status);
    367     return;
    368   }
    369 
    370   DumpMessage(false, buffer->data(), result);
    371   std::vector<uint32> header(6);
    372   memcpy(&header[0], buffer->data(), result);
    373   scoped_refptr<AdbMessage> message =
    374       new AdbMessage(header[0], header[1], header[2], "");
    375   uint32 data_length = header[3];
    376   uint32 data_check = header[4];
    377   uint32 magic = header[5];
    378   if ((message->command ^ 0xffffffff) != magic) {
    379     TransferError(USB_TRANSFER_ERROR);
    380     return;
    381   }
    382 
    383   if (data_length == 0) {
    384     message_loop_->PostTask(FROM_HERE,
    385                             base::Bind(&AndroidUsbDevice::HandleIncoming, this,
    386                                        message));
    387     return;
    388   }
    389 
    390   message_loop_->PostTask(FROM_HERE,
    391                           base::Bind(&AndroidUsbDevice::ReadBody, this,
    392                                      message, data_length, data_check));
    393 }
    394 
    395 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message,
    396                                 uint32 data_length,
    397                                 uint32 data_check) {
    398   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length);
    399   usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_,
    400       buffer, data_length, kUsbTimeout,
    401       base::Bind(&AndroidUsbDevice::ParseBody, this, message, data_length,
    402                  data_check));
    403 }
    404 
    405 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message,
    406                                  uint32 data_length,
    407                                  uint32 data_check,
    408                                  UsbTransferStatus status,
    409                                  scoped_refptr<net::IOBuffer> buffer,
    410                                  size_t result) {
    411   if (status == USB_TRANSFER_TIMEOUT) {
    412     message_loop_->PostTask(FROM_HERE,
    413                             base::Bind(&AndroidUsbDevice::ReadBody, this,
    414                             message, data_length, data_check));
    415     return;
    416   }
    417 
    418   if (status != USB_TRANSFER_COMPLETED ||
    419       static_cast<uint32>(result) != data_length) {
    420     TransferError(status);
    421     return;
    422   }
    423 
    424   DumpMessage(false, buffer->data(), data_length);
    425   message->body = std::string(buffer->data(), result);
    426   if (Checksum(message->body) != data_check) {
    427     TransferError(USB_TRANSFER_ERROR);
    428     return;
    429   }
    430 
    431   message_loop_->PostTask(FROM_HERE,
    432                           base::Bind(&AndroidUsbDevice::HandleIncoming, this,
    433                                      message));
    434 }
    435 
    436 void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) {
    437   switch (message->command) {
    438     case AdbMessage::kCommandAUTH:
    439       {
    440         DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken));
    441         if (signature_sent_) {
    442           Queue(new AdbMessage(AdbMessage::kCommandAUTH,
    443                                AdbMessage::kAuthRSAPublicKey, 0,
    444                                AndroidRSAPublicKey(rsa_key_.get())));
    445         } else {
    446           signature_sent_ = true;
    447           std::string signature = AndroidRSASign(rsa_key_.get(), message->body);
    448           if (!signature.empty()) {
    449             Queue(new AdbMessage(AdbMessage::kCommandAUTH,
    450                                  AdbMessage::kAuthSignature, 0,
    451                                  signature));
    452           } else {
    453             Queue(new AdbMessage(AdbMessage::kCommandAUTH,
    454                                  AdbMessage::kAuthRSAPublicKey, 0,
    455                                  AndroidRSAPublicKey(rsa_key_.get())));
    456           }
    457         }
    458       }
    459       break;
    460     case AdbMessage::kCommandCNXN:
    461       {
    462         is_connected_ = true;
    463         PendingMessages pending;
    464         pending.swap(pending_messages_);
    465         for (PendingMessages::iterator it = pending.begin();
    466              it != pending.end(); ++it) {
    467           Queue(*it);
    468         }
    469       }
    470       break;
    471     case AdbMessage::kCommandOKAY:
    472     case AdbMessage::kCommandWRTE:
    473     case AdbMessage::kCommandCLSE:
    474       {
    475         AndroidUsbSockets::iterator it = sockets_.find(message->arg1);
    476         if (it != sockets_.end())
    477           it->second->HandleIncoming(message);
    478       }
    479       break;
    480     default:
    481       break;
    482   }
    483   ReadHeader(false);
    484 }
    485 
    486 void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
    487   message_loop_->PostTask(FROM_HERE,
    488                           base::Bind(&AndroidUsbDevice::Terminate,
    489                                      this));
    490 }
    491 
    492 void AndroidUsbDevice::Terminate() {
    493   if (terminated_)
    494     return;
    495 
    496   terminated_ = true;
    497 
    498   // Iterate over copy.
    499   AndroidUsbSockets sockets(sockets_);
    500   for (AndroidUsbSockets::iterator it = sockets.begin();
    501        it != sockets.end(); ++it) {
    502     it->second->Terminated();
    503   }
    504 
    505   usb_device_->ReleaseInterface(1);
    506   usb_device_->Close();
    507 }
    508 
    509 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
    510   sockets_.erase(socket_id);
    511 }
    512