Home | History | Annotate | Download | only in usb
      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 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 
    108 uint32 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 
    117 void 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 
    146 void 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 
    154 AdbMessage::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 
    164 AdbMessage::~AdbMessage() {
    165 }
    166 
    167 static 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 
    182 static 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 
    192 static 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 
    219 static 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 
    242 static 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
    288 void 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
    298 void 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 
    317 AndroidUsbDevice::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 
    338 void 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 
    347 net::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 
    357 void 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 
    370 AndroidUsbDevice::~AndroidUsbDevice() {
    371   DCHECK(message_loop_ == base::MessageLoop::current());
    372   Terminate();
    373 }
    374 
    375 void 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 
    417 void 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 
    435 void 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 
    446 void 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 
    461 void 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 
    502 void 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 
    522 void 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 
    555 void 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 
    607 void 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 
    614 void 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 
    623 void 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 
    652 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
    653   DCHECK(message_loop_ == base::MessageLoop::current());
    654 
    655   sockets_.erase(socket_id);
    656 }
    657