OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/devtools/device/usb/android_usb_device.h" | 5 #include "chrome/browser/devtools/device/usb/android_usb_device.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/barrier_closure.h" | 9 #include "base/barrier_closure.h" |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 AdbMessage::~AdbMessage() { | 173 AdbMessage::~AdbMessage() { |
174 } | 174 } |
175 | 175 |
176 static void RespondOnCallerThread(const AndroidUsbDevicesCallback& callback, | 176 static void RespondOnCallerThread(const AndroidUsbDevicesCallback& callback, |
177 AndroidUsbDevices* new_devices) { | 177 AndroidUsbDevices* new_devices) { |
178 scoped_ptr<AndroidUsbDevices> devices(new_devices); | 178 scoped_ptr<AndroidUsbDevices> devices(new_devices); |
179 | 179 |
180 // Add raw pointers to the newly claimed devices. | 180 // Add raw pointers to the newly claimed devices. |
181 for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end(); | 181 for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end(); |
182 ++it) { | 182 ++it) { |
183 g_devices.Get().push_back(*it); | 183 g_devices.Get().push_back(it->get()); |
184 } | 184 } |
185 | 185 |
186 // Return all claimed devices. | 186 // Return all claimed devices. |
187 AndroidUsbDevices result(g_devices.Get().begin(), g_devices.Get().end()); | 187 AndroidUsbDevices result(g_devices.Get().begin(), g_devices.Get().end()); |
188 callback.Run(result); | 188 callback.Run(result); |
189 } | 189 } |
190 | 190 |
191 static void RespondOnFileThread( | 191 static void RespondOnFileThread( |
192 const AndroidUsbDevicesCallback& callback, | 192 const AndroidUsbDevicesCallback& callback, |
193 AndroidUsbDevices* devices, | 193 AndroidUsbDevices* devices, |
194 scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) { | 194 scoped_refptr<base::MessageLoopProxy> caller_message_loop_proxy) { |
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
196 caller_message_loop_proxy->PostTask( | 196 caller_message_loop_proxy->PostTask( |
197 FROM_HERE, | 197 FROM_HERE, |
198 base::Bind(&RespondOnCallerThread, callback, devices)); | 198 base::Bind(&RespondOnCallerThread, callback, devices)); |
199 } | 199 } |
200 | 200 |
201 static void OpenAndroidDeviceOnFileThread( | 201 static void OpenAndroidDeviceOnFileThread( |
202 AndroidUsbDevices* devices, | 202 AndroidUsbDevices* devices, |
203 crypto::RSAPrivateKey* rsa_key, | 203 crypto::RSAPrivateKey* rsa_key, |
204 const base::Closure& barrier, | 204 const base::Closure& barrier, |
205 scoped_refptr<UsbDevice> device, | 205 scoped_refptr<UsbDevice> device, |
206 int interface_id, | 206 int interface_id, |
207 bool success) { | 207 bool success) { |
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
209 if (success) { | 209 if (success) { |
210 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces(); | 210 scoped_refptr<UsbConfigDescriptor> config = device->ListInterfaces(); |
211 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open(); | 211 scoped_refptr<UsbDeviceHandle> usb_handle = device->Open(); |
212 if (usb_handle) { | 212 if (usb_handle.get()) { |
213 scoped_refptr<AndroidUsbDevice> android_device = | 213 scoped_refptr<AndroidUsbDevice> android_device = |
214 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id), | 214 ClaimInterface(rsa_key, usb_handle, config->GetInterface(interface_id), |
215 interface_id); | 215 interface_id); |
216 if (android_device.get()) | 216 if (android_device.get()) |
217 devices->push_back(android_device.get()); | 217 devices->push_back(android_device.get()); |
218 else | 218 else |
219 usb_handle->Close(); | 219 usb_handle->Close(); |
220 } | 220 } |
221 } | 221 } |
222 barrier.Run(); | 222 barrier.Run(); |
223 } | 223 } |
224 | 224 |
225 static int CountOnFileThread() { | 225 static int CountOnFileThread() { |
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
227 UsbService* service = UsbService::GetInstance(); | 227 UsbService* service = UsbService::GetInstance(); |
228 UsbDevices usb_devices; | 228 UsbDevices usb_devices; |
229 if (service != NULL) | 229 if (service != NULL) |
230 service->GetDevices(&usb_devices); | 230 service->GetDevices(&usb_devices); |
231 int device_count = 0; | 231 int device_count = 0; |
232 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); | 232 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); |
233 ++it) { | 233 ++it) { |
234 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); | 234 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); |
235 if (!config) | 235 if (!config.get()) |
236 continue; | 236 continue; |
237 | 237 |
238 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { | 238 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { |
239 if (IsAndroidInterface(config->GetInterface(j))) | 239 if (IsAndroidInterface(config->GetInterface(j))) |
240 ++device_count; | 240 ++device_count; |
241 } | 241 } |
242 } | 242 } |
243 return device_count; | 243 return device_count; |
244 } | 244 } |
245 | 245 |
(...skipping 12 matching lines...) Expand all Loading... |
258 AndroidUsbDevices* devices = new AndroidUsbDevices(); | 258 AndroidUsbDevices* devices = new AndroidUsbDevices(); |
259 base::Closure barrier = base::BarrierClosure( | 259 base::Closure barrier = base::BarrierClosure( |
260 usb_devices.size(), base::Bind(&RespondOnFileThread, | 260 usb_devices.size(), base::Bind(&RespondOnFileThread, |
261 callback, | 261 callback, |
262 devices, | 262 devices, |
263 caller_message_loop_proxy)); | 263 caller_message_loop_proxy)); |
264 | 264 |
265 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); | 265 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); |
266 ++it) { | 266 ++it) { |
267 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); | 267 scoped_refptr<UsbConfigDescriptor> config = (*it)->ListInterfaces(); |
268 if (!config) { | 268 if (!config.get()) { |
269 barrier.Run(); | 269 barrier.Run(); |
270 continue; | 270 continue; |
271 } | 271 } |
272 | 272 |
273 bool has_android_interface = false; | 273 bool has_android_interface = false; |
274 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { | 274 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { |
275 if (!IsAndroidInterface(config->GetInterface(j))) | 275 if (!IsAndroidInterface(config->GetInterface(j))) |
276 continue; | 276 continue; |
277 | 277 |
278 // Request permission on Chrome OS. | 278 // Request permission on Chrome OS. |
(...skipping 22 matching lines...) Expand all Loading... |
301 callback); | 301 callback); |
302 } | 302 } |
303 | 303 |
304 // static | 304 // static |
305 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key, | 305 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key, |
306 const AndroidUsbDevicesCallback& callback) { | 306 const AndroidUsbDevicesCallback& callback) { |
307 | 307 |
308 // Collect devices with closed handles. | 308 // Collect devices with closed handles. |
309 for (std::vector<AndroidUsbDevice*>::iterator it = g_devices.Get().begin(); | 309 for (std::vector<AndroidUsbDevice*>::iterator it = g_devices.Get().begin(); |
310 it != g_devices.Get().end(); ++it) { | 310 it != g_devices.Get().end(); ++it) { |
311 if ((*it)->usb_handle_) { | 311 if ((*it)->usb_handle_.get()) { |
312 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 312 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
313 base::Bind(&AndroidUsbDevice::TerminateIfReleased, *it, | 313 base::Bind(&AndroidUsbDevice::TerminateIfReleased, *it, |
314 (*it)->usb_handle_)); | 314 (*it)->usb_handle_)); |
315 } | 315 } |
316 } | 316 } |
317 | 317 |
318 // Then look for the new devices. | 318 // Then look for the new devices. |
319 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 319 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
320 base::Bind(&EnumerateOnFileThread, rsa_key, callback, | 320 base::Bind(&EnumerateOnFileThread, rsa_key, callback, |
321 base::MessageLoopProxy::current())); | 321 base::MessageLoopProxy::current())); |
(...skipping 23 matching lines...) Expand all Loading... |
345 void AndroidUsbDevice::InitOnCallerThread() { | 345 void AndroidUsbDevice::InitOnCallerThread() { |
346 if (message_loop_) | 346 if (message_loop_) |
347 return; | 347 return; |
348 message_loop_ = base::MessageLoop::current(); | 348 message_loop_ = base::MessageLoop::current(); |
349 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload, | 349 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload, |
350 kHostConnectMessage)); | 350 kHostConnectMessage)); |
351 ReadHeader(); | 351 ReadHeader(); |
352 } | 352 } |
353 | 353 |
354 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) { | 354 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) { |
355 if (!usb_handle_) | 355 if (!usb_handle_.get()) |
356 return NULL; | 356 return NULL; |
357 | 357 |
358 uint32 socket_id = ++last_socket_id_; | 358 uint32 socket_id = ++last_socket_id_; |
359 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command, | 359 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command, |
360 base::Bind(&AndroidUsbDevice::SocketDeleted, this)); | 360 base::Bind(&AndroidUsbDevice::SocketDeleted, this)); |
361 return sockets_[socket_id]; | 361 return sockets_[socket_id]; |
362 } | 362 } |
363 | 363 |
364 void AndroidUsbDevice::Send(uint32 command, | 364 void AndroidUsbDevice::Send(uint32 command, |
365 uint32 arg0, | 365 uint32 arg0, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 // Send a zero length packet. | 417 // Send a zero length packet. |
418 outgoing_queue_.push(new net::IOBufferWithSize(0)); | 418 outgoing_queue_.push(new net::IOBufferWithSize(0)); |
419 } | 419 } |
420 } | 420 } |
421 ProcessOutgoing(); | 421 ProcessOutgoing(); |
422 } | 422 } |
423 | 423 |
424 void AndroidUsbDevice::ProcessOutgoing() { | 424 void AndroidUsbDevice::ProcessOutgoing() { |
425 DCHECK(message_loop_ == base::MessageLoop::current()); | 425 DCHECK(message_loop_ == base::MessageLoop::current()); |
426 | 426 |
427 if (outgoing_queue_.empty() || !usb_handle_) | 427 if (outgoing_queue_.empty() || !usb_handle_.get()) |
428 return; | 428 return; |
429 | 429 |
430 BulkMessage message = outgoing_queue_.front(); | 430 BulkMessage message = outgoing_queue_.front(); |
431 outgoing_queue_.pop(); | 431 outgoing_queue_.pop(); |
432 DumpMessage(true, message->data(), message->size()); | 432 DumpMessage(true, message->data(), message->size()); |
433 usb_handle_->BulkTransfer( | 433 usb_handle_->BulkTransfer(usb_service::USB_DIRECTION_OUTBOUND, |
434 usb_service::USB_DIRECTION_OUTBOUND, outbound_address_, | 434 outbound_address_, |
435 message, message->size(), kUsbTimeout, | 435 message.get(), |
436 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, | 436 message->size(), |
437 weak_factory_.GetWeakPtr())); | 437 kUsbTimeout, |
| 438 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, |
| 439 weak_factory_.GetWeakPtr())); |
438 } | 440 } |
439 | 441 |
440 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, | 442 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, |
441 scoped_refptr<net::IOBuffer> buffer, | 443 scoped_refptr<net::IOBuffer> buffer, |
442 size_t result) { | 444 size_t result) { |
443 DCHECK(message_loop_ == base::MessageLoop::current()); | 445 DCHECK(message_loop_ == base::MessageLoop::current()); |
444 | 446 |
445 if (status != usb_service::USB_TRANSFER_COMPLETED) | 447 if (status != usb_service::USB_TRANSFER_COMPLETED) |
446 return; | 448 return; |
447 message_loop_->PostTask(FROM_HERE, | 449 message_loop_->PostTask(FROM_HERE, |
448 base::Bind(&AndroidUsbDevice::ProcessOutgoing, this)); | 450 base::Bind(&AndroidUsbDevice::ProcessOutgoing, this)); |
449 } | 451 } |
450 | 452 |
451 void AndroidUsbDevice::ReadHeader() { | 453 void AndroidUsbDevice::ReadHeader() { |
452 DCHECK(message_loop_ == base::MessageLoop::current()); | 454 DCHECK(message_loop_ == base::MessageLoop::current()); |
453 | 455 |
454 if (!usb_handle_) | 456 if (!usb_handle_.get()) |
455 return; | 457 return; |
456 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize); | 458 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize); |
457 usb_handle_->BulkTransfer( | 459 usb_handle_->BulkTransfer( |
458 usb_service::USB_DIRECTION_INBOUND, inbound_address_, | 460 usb_service::USB_DIRECTION_INBOUND, |
459 buffer, kHeaderSize, kUsbTimeout, | 461 inbound_address_, |
460 base::Bind(&AndroidUsbDevice::ParseHeader, | 462 buffer.get(), |
461 weak_factory_.GetWeakPtr())); | 463 kHeaderSize, |
| 464 kUsbTimeout, |
| 465 base::Bind(&AndroidUsbDevice::ParseHeader, weak_factory_.GetWeakPtr())); |
462 } | 466 } |
463 | 467 |
464 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status, | 468 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status, |
465 scoped_refptr<net::IOBuffer> buffer, | 469 scoped_refptr<net::IOBuffer> buffer, |
466 size_t result) { | 470 size_t result) { |
467 DCHECK(message_loop_ == base::MessageLoop::current()); | 471 DCHECK(message_loop_ == base::MessageLoop::current()); |
468 | 472 |
469 if (status == usb_service::USB_TRANSFER_TIMEOUT) { | 473 if (status == usb_service::USB_TRANSFER_TIMEOUT) { |
470 message_loop_->PostTask(FROM_HERE, | 474 message_loop_->PostTask(FROM_HERE, |
471 base::Bind(&AndroidUsbDevice::ReadHeader, this)); | 475 base::Bind(&AndroidUsbDevice::ReadHeader, this)); |
(...skipping 28 matching lines...) Expand all Loading... |
500 message_loop_->PostTask(FROM_HERE, | 504 message_loop_->PostTask(FROM_HERE, |
501 base::Bind(&AndroidUsbDevice::ReadBody, this, | 505 base::Bind(&AndroidUsbDevice::ReadBody, this, |
502 message, data_length, data_check)); | 506 message, data_length, data_check)); |
503 } | 507 } |
504 | 508 |
505 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message, | 509 void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message, |
506 uint32 data_length, | 510 uint32 data_length, |
507 uint32 data_check) { | 511 uint32 data_check) { |
508 DCHECK(message_loop_ == base::MessageLoop::current()); | 512 DCHECK(message_loop_ == base::MessageLoop::current()); |
509 | 513 |
510 if (!usb_handle_) | 514 if (!usb_handle_.get()) |
511 return; | 515 return; |
512 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length); | 516 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length); |
513 usb_handle_->BulkTransfer( | 517 usb_handle_->BulkTransfer(usb_service::USB_DIRECTION_INBOUND, |
514 usb_service::USB_DIRECTION_INBOUND, inbound_address_, | 518 inbound_address_, |
515 buffer, data_length, kUsbTimeout, | 519 buffer.get(), |
516 base::Bind(&AndroidUsbDevice::ParseBody, weak_factory_.GetWeakPtr(), | 520 data_length, |
517 message, data_length, data_check)); | 521 kUsbTimeout, |
| 522 base::Bind(&AndroidUsbDevice::ParseBody, |
| 523 weak_factory_.GetWeakPtr(), |
| 524 message, |
| 525 data_length, |
| 526 data_check)); |
518 } | 527 } |
519 | 528 |
520 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message, | 529 void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message, |
521 uint32 data_length, | 530 uint32 data_length, |
522 uint32 data_check, | 531 uint32 data_check, |
523 UsbTransferStatus status, | 532 UsbTransferStatus status, |
524 scoped_refptr<net::IOBuffer> buffer, | 533 scoped_refptr<net::IOBuffer> buffer, |
525 size_t result) { | 534 size_t result) { |
526 DCHECK(message_loop_ == base::MessageLoop::current()); | 535 DCHECK(message_loop_ == base::MessageLoop::current()); |
527 | 536 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 } | 628 } |
620 | 629 |
621 void AndroidUsbDevice::Terminate() { | 630 void AndroidUsbDevice::Terminate() { |
622 DCHECK(message_loop_ == base::MessageLoop::current()); | 631 DCHECK(message_loop_ == base::MessageLoop::current()); |
623 | 632 |
624 std::vector<AndroidUsbDevice*>::iterator it = | 633 std::vector<AndroidUsbDevice*>::iterator it = |
625 std::find(g_devices.Get().begin(), g_devices.Get().end(), this); | 634 std::find(g_devices.Get().begin(), g_devices.Get().end(), this); |
626 if (it != g_devices.Get().end()) | 635 if (it != g_devices.Get().end()) |
627 g_devices.Get().erase(it); | 636 g_devices.Get().erase(it); |
628 | 637 |
629 if (!usb_handle_) | 638 if (!usb_handle_.get()) |
630 return; | 639 return; |
631 | 640 |
632 // Make sure we zero-out handle so that closing connections did not open | 641 // Make sure we zero-out handle so that closing connections did not open |
633 // new connections. | 642 // new connections. |
634 scoped_refptr<UsbDeviceHandle> usb_handle = usb_handle_; | 643 scoped_refptr<UsbDeviceHandle> usb_handle = usb_handle_; |
635 usb_handle_ = NULL; | 644 usb_handle_ = NULL; |
636 | 645 |
637 // Iterate over copy. | 646 // Iterate over copy. |
638 AndroidUsbSockets sockets(sockets_); | 647 AndroidUsbSockets sockets(sockets_); |
639 for (AndroidUsbSockets::iterator it = sockets.begin(); | 648 for (AndroidUsbSockets::iterator it = sockets.begin(); |
640 it != sockets.end(); ++it) { | 649 it != sockets.end(); ++it) { |
641 it->second->Terminated(true); | 650 it->second->Terminated(true); |
642 } | 651 } |
643 DCHECK(sockets_.empty()); | 652 DCHECK(sockets_.empty()); |
644 | 653 |
645 BrowserThread::PostTask( | 654 BrowserThread::PostTask( |
646 BrowserThread::FILE, FROM_HERE, | 655 BrowserThread::FILE, FROM_HERE, |
647 base::Bind(&ReleaseInterface, usb_handle, interface_id_)); | 656 base::Bind(&ReleaseInterface, usb_handle, interface_id_)); |
648 } | 657 } |
649 | 658 |
650 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { | 659 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { |
651 DCHECK(message_loop_ == base::MessageLoop::current()); | 660 DCHECK(message_loop_ == base::MessageLoop::current()); |
652 | 661 |
653 sockets_.erase(socket_id); | 662 sockets_.erase(socket_id); |
654 } | 663 } |
OLD | NEW |