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