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