| 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 |