• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IsAndroidInterface(const UsbInterfaceDescriptor & interface)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 
ClaimInterface(crypto::RSAPrivateKey * rsa_key,scoped_refptr<UsbDeviceHandle> usb_handle,const base::string16 & serial,const UsbInterfaceDescriptor & interface)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 
Checksum(const std::string & data)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 
DumpMessage(bool outgoing,const char * data,size_t length)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 
ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device,int interface_id)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 
AdbMessage(uint32 command,uint32 arg0,uint32 arg1,const std::string & body)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 
~AdbMessage()164 AdbMessage::~AdbMessage() {
165 }
166 
RespondOnCallerThread(const AndroidUsbDevicesCallback & callback,AndroidUsbDevices * new_devices)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 
RespondOnFileThread(const AndroidUsbDevicesCallback & callback,AndroidUsbDevices * devices,scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy)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 
OpenAndroidDeviceOnFileThread(AndroidUsbDevices * devices,crypto::RSAPrivateKey * rsa_key,const base::Closure & barrier,scoped_refptr<UsbDevice> device,int interface_id,bool success)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 
CountOnFileThread()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 
EnumerateOnFileThread(crypto::RSAPrivateKey * rsa_key,const AndroidUsbDevicesCallback & callback,scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy)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
CountDevices(const base::Callback<void (int)> & callback)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
Enumerate(crypto::RSAPrivateKey * rsa_key,const AndroidUsbDevicesCallback & callback)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 
AndroidUsbDevice(crypto::RSAPrivateKey * rsa_key,scoped_refptr<UsbDeviceHandle> usb_device,const std::string & serial,int inbound_address,int outbound_address,int zero_mask,int interface_id)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 
InitOnCallerThread()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 
CreateSocket(const std::string & command)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 
Send(uint32 command,uint32 arg0,uint32 arg1,const std::string & body)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 
~AndroidUsbDevice()370 AndroidUsbDevice::~AndroidUsbDevice() {
371   DCHECK(message_loop_ == base::MessageLoop::current());
372   Terminate();
373 }
374 
Queue(scoped_refptr<AdbMessage> message)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 
ProcessOutgoing()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 
OutgoingMessageSent(UsbTransferStatus status,scoped_refptr<net::IOBuffer> buffer,size_t result)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 
ReadHeader()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 
ParseHeader(UsbTransferStatus status,scoped_refptr<net::IOBuffer> buffer,size_t result)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 
ReadBody(scoped_refptr<AdbMessage> message,uint32 data_length,uint32 data_check)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 
ParseBody(scoped_refptr<AdbMessage> message,uint32 data_length,uint32 data_check,UsbTransferStatus status,scoped_refptr<net::IOBuffer> buffer,size_t result)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 
HandleIncoming(scoped_refptr<AdbMessage> message)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 
TransferError(UsbTransferStatus status)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 
TerminateIfReleased(scoped_refptr<UsbDeviceHandle> usb_handle)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 
Terminate()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 
SocketDeleted(uint32 socket_id)652 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
653   DCHECK(message_loop_ == base::MessageLoop::current());
654 
655   sockets_.erase(socket_id);
656 }
657