Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / devtools / device / usb / android_usb_device.cc
blob33efd00594e4f84f369ff5879c46a50e53fc9be3
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.
5 #include "chrome/browser/devtools/device/usb/android_usb_device.h"
7 #include <set>
9 #include "base/barrier_closure.h"
10 #include "base/base64.h"
11 #include "base/lazy_instance.h"
12 #include "base/single_thread_task_runner.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 "base/thread_task_runner_handle.h"
18 #include "chrome/browser/devtools/device/usb/android_rsa.h"
19 #include "chrome/browser/devtools/device/usb/android_usb_socket.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "crypto/rsa_private_key.h"
22 #include "device/core/device_client.h"
23 #include "device/usb/usb_descriptors.h"
24 #include "device/usb/usb_device.h"
25 #include "device/usb/usb_service.h"
26 #include "net/base/ip_endpoint.h"
27 #include "net/base/net_errors.h"
28 #include "net/socket/stream_socket.h"
30 using device::UsbConfigDescriptor;
31 using device::UsbDevice;
32 using device::UsbDeviceHandle;
33 using device::UsbInterfaceDescriptor;
34 using device::UsbEndpointDescriptor;
35 using device::UsbService;
36 using device::UsbTransferStatus;
38 namespace {
40 const size_t kHeaderSize = 24;
42 const int kAdbClass = 0xff;
43 const int kAdbSubclass = 0x42;
44 const int kAdbProtocol = 0x1;
46 const int kUsbTimeout = 0;
48 const uint32 kMaxPayload = 4096;
49 const uint32 kVersion = 0x01000000;
51 static const char kHostConnectMessage[] = "host::";
53 using content::BrowserThread;
55 typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices;
56 typedef std::set<scoped_refptr<UsbDevice> > UsbDeviceSet;
58 // Stores android wrappers around claimed usb devices on caller thread.
59 base::LazyInstance<std::vector<AndroidUsbDevice*> >::Leaky g_devices =
60 LAZY_INSTANCE_INITIALIZER;
62 bool IsAndroidInterface(const UsbInterfaceDescriptor& interface) {
63 if (interface.alternate_setting != 0 ||
64 interface.interface_class != kAdbClass ||
65 interface.interface_subclass != kAdbSubclass ||
66 interface.interface_protocol != kAdbProtocol ||
67 interface.endpoints.size() != 2) {
68 return false;
70 return true;
73 void CountAndroidDevices(const base::Callback<void(int)>& callback,
74 const UsbDevices& devices) {
75 int device_count = 0;
76 for (const scoped_refptr<UsbDevice>& device : devices) {
77 const UsbConfigDescriptor* config = device->GetActiveConfiguration();
78 if (config) {
79 for (const UsbInterfaceDescriptor& iface : config->interfaces) {
80 if (IsAndroidInterface(iface)) {
81 ++device_count;
87 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
88 base::Bind(callback, device_count));
91 uint32 Checksum(const std::string& data) {
92 unsigned char* x = (unsigned char*)data.data();
93 int count = data.length();
94 uint32 sum = 0;
95 while (count-- > 0)
96 sum += *x++;
97 return sum;
100 void DumpMessage(bool outgoing, const char* data, size_t length) {
101 #if 0
102 std::string result = "";
103 if (length == kHeaderSize) {
104 for (size_t i = 0; i < 24; ++i) {
105 result += base::StringPrintf("%02x",
106 data[i] > 0 ? data[i] : (data[i] + 0x100) & 0xFF);
107 if ((i + 1) % 4 == 0)
108 result += " ";
110 for (size_t i = 0; i < 24; ++i) {
111 if (data[i] >= 0x20 && data[i] <= 0x7E)
112 result += data[i];
113 else
114 result += ".";
116 } else {
117 result = base::StringPrintf("%d: ", (int)length);
118 for (size_t i = 0; i < length; ++i) {
119 if (data[i] >= 0x20 && data[i] <= 0x7E)
120 result += data[i];
121 else
122 result += ".";
125 LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result;
126 #endif // 0
129 void ReleaseInterface(scoped_refptr<UsbDeviceHandle> usb_device,
130 int interface_id) {
131 usb_device->ReleaseInterface(interface_id);
132 usb_device->Close();
135 void RespondOnCallerThread(const AndroidUsbDevicesCallback& callback,
136 AndroidUsbDevices* new_devices) {
137 scoped_ptr<AndroidUsbDevices> devices(new_devices);
139 // Add raw pointers to the newly claimed devices.
140 for (const scoped_refptr<AndroidUsbDevice>& device : *devices) {
141 g_devices.Get().push_back(device.get());
144 // Return all claimed devices.
145 AndroidUsbDevices result(g_devices.Get().begin(), g_devices.Get().end());
146 callback.Run(result);
149 void RespondOnUIThread(
150 const AndroidUsbDevicesCallback& callback,
151 AndroidUsbDevices* devices,
152 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner) {
153 DCHECK_CURRENTLY_ON(BrowserThread::UI);
154 caller_task_runner->PostTask(
155 FROM_HERE, base::Bind(&RespondOnCallerThread, callback, devices));
158 void CreateDeviceOnInterfaceClaimed(AndroidUsbDevices* devices,
159 crypto::RSAPrivateKey* rsa_key,
160 scoped_refptr<UsbDeviceHandle> usb_handle,
161 int inbound_address,
162 int outbound_address,
163 int zero_mask,
164 int interface_number,
165 const base::Closure& barrier,
166 bool success) {
167 DCHECK_CURRENTLY_ON(BrowserThread::UI);
168 if (success) {
169 devices->push_back(new AndroidUsbDevice(
170 rsa_key, usb_handle,
171 base::UTF16ToASCII(usb_handle->GetDevice()->serial_number()),
172 inbound_address, outbound_address, zero_mask, interface_number));
173 } else {
174 usb_handle->Close();
176 barrier.Run();
179 void OnDeviceOpened(AndroidUsbDevices* devices,
180 crypto::RSAPrivateKey* rsa_key,
181 int inbound_address,
182 int outbound_address,
183 int zero_mask,
184 int interface_number,
185 const base::Closure& barrier,
186 scoped_refptr<UsbDeviceHandle> usb_handle) {
187 DCHECK_CURRENTLY_ON(BrowserThread::UI);
188 if (usb_handle.get()) {
189 usb_handle->ClaimInterface(
190 interface_number,
191 base::Bind(&CreateDeviceOnInterfaceClaimed, devices, rsa_key,
192 usb_handle, inbound_address, outbound_address, zero_mask,
193 interface_number, barrier));
194 } else {
195 barrier.Run();
199 void OpenAndroidDevice(AndroidUsbDevices* devices,
200 crypto::RSAPrivateKey* rsa_key,
201 const base::Closure& barrier,
202 scoped_refptr<UsbDevice> device,
203 int interface_id) {
204 DCHECK_CURRENTLY_ON(BrowserThread::UI);
205 if (device->serial_number().empty()) {
206 barrier.Run();
207 return;
210 const UsbConfigDescriptor* config = device->GetActiveConfiguration();
211 if (!config) {
212 barrier.Run();
213 return;
216 const UsbInterfaceDescriptor& interface = config->interfaces[interface_id];
217 int inbound_address = 0;
218 int outbound_address = 0;
219 int zero_mask = 0;
221 for (const UsbEndpointDescriptor& endpoint : interface.endpoints) {
222 if (endpoint.transfer_type != device::USB_TRANSFER_BULK)
223 continue;
224 if (endpoint.direction == device::USB_DIRECTION_INBOUND)
225 inbound_address = endpoint.address;
226 else
227 outbound_address = endpoint.address;
228 zero_mask = endpoint.maximum_packet_size - 1;
231 if (inbound_address == 0 || outbound_address == 0) {
232 barrier.Run();
233 return;
236 device->Open(base::Bind(&OnDeviceOpened, devices, rsa_key, inbound_address,
237 outbound_address, zero_mask,
238 interface.interface_number, barrier));
241 void OpenAndroidDevices(
242 crypto::RSAPrivateKey* rsa_key,
243 const AndroidUsbDevicesCallback& callback,
244 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
245 const UsbDevices& usb_devices) {
246 DCHECK_CURRENTLY_ON(BrowserThread::UI);
247 // Add new devices.
248 AndroidUsbDevices* devices = new AndroidUsbDevices();
249 base::Closure barrier = base::BarrierClosure(
250 usb_devices.size(),
251 base::Bind(&RespondOnUIThread, callback, devices, caller_task_runner));
253 for (const scoped_refptr<UsbDevice>& device : usb_devices) {
254 const UsbConfigDescriptor* config = device->GetActiveConfiguration();
255 if (!config) {
256 barrier.Run();
257 continue;
259 bool has_android_interface = false;
260 for (size_t j = 0; j < config->interfaces.size(); ++j) {
261 if (!IsAndroidInterface(config->interfaces[j])) {
262 continue;
265 OpenAndroidDevice(devices, rsa_key, barrier, device, j);
266 has_android_interface = true;
267 break;
269 if (!has_android_interface) {
270 barrier.Run();
275 void EnumerateOnUIThread(
276 crypto::RSAPrivateKey* rsa_key,
277 const AndroidUsbDevicesCallback& callback,
278 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner) {
279 DCHECK_CURRENTLY_ON(BrowserThread::UI);
281 UsbService* service = device::DeviceClient::Get()->GetUsbService();
282 if (service == NULL) {
283 caller_task_runner->PostTask(FROM_HERE,
284 base::Bind(callback, AndroidUsbDevices()));
285 } else {
286 service->GetDevices(
287 base::Bind(&OpenAndroidDevices, rsa_key, callback, caller_task_runner));
291 } // namespace
293 AdbMessage::AdbMessage(uint32 command,
294 uint32 arg0,
295 uint32 arg1,
296 const std::string& body)
297 : command(command), arg0(arg0), arg1(arg1), body(body) {
300 AdbMessage::~AdbMessage() {
303 // static
304 void AndroidUsbDevice::CountDevices(const base::Callback<void(int)>& callback) {
305 UsbService* service = device::DeviceClient::Get()->GetUsbService();
306 if (service != NULL) {
307 service->GetDevices(base::Bind(&CountAndroidDevices, callback));
308 } else {
309 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
310 base::Bind(callback, 0));
314 // static
315 void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key,
316 const AndroidUsbDevicesCallback& callback) {
317 // Collect devices with closed handles.
318 for (AndroidUsbDevice* device : g_devices.Get()) {
319 if (device->usb_handle_.get()) {
320 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
321 base::Bind(&AndroidUsbDevice::TerminateIfReleased,
322 device, device->usb_handle_));
326 // Then look for the new devices.
327 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
328 base::Bind(&EnumerateOnUIThread, rsa_key, callback,
329 base::ThreadTaskRunnerHandle::Get()));
332 AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
333 scoped_refptr<UsbDeviceHandle> usb_device,
334 const std::string& serial,
335 int inbound_address,
336 int outbound_address,
337 int zero_mask,
338 int interface_id)
339 : rsa_key_(rsa_key->Copy()),
340 usb_handle_(usb_device),
341 serial_(serial),
342 inbound_address_(inbound_address),
343 outbound_address_(outbound_address),
344 zero_mask_(zero_mask),
345 interface_id_(interface_id),
346 is_connected_(false),
347 signature_sent_(false),
348 last_socket_id_(256),
349 weak_factory_(this) {
352 void AndroidUsbDevice::InitOnCallerThread() {
353 if (task_runner_)
354 return;
355 task_runner_ = base::ThreadTaskRunnerHandle::Get();
356 Queue(make_scoped_ptr(new AdbMessage(AdbMessage::kCommandCNXN, kVersion,
357 kMaxPayload, kHostConnectMessage)));
358 ReadHeader();
361 net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) {
362 if (!usb_handle_.get())
363 return NULL;
365 uint32 socket_id = ++last_socket_id_;
366 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command,
367 base::Bind(&AndroidUsbDevice::SocketDeleted, this, socket_id));
368 return sockets_[socket_id];
371 void AndroidUsbDevice::Send(uint32 command,
372 uint32 arg0,
373 uint32 arg1,
374 const std::string& body) {
375 scoped_ptr<AdbMessage> message(new AdbMessage(command, arg0, arg1, body));
376 // Delay open request if not yet connected.
377 if (!is_connected_) {
378 pending_messages_.push_back(message.release());
379 return;
381 Queue(message.Pass());
384 AndroidUsbDevice::~AndroidUsbDevice() {
385 DCHECK(task_runner_->BelongsToCurrentThread());
386 Terminate();
389 void AndroidUsbDevice::Queue(scoped_ptr<AdbMessage> message) {
390 DCHECK(task_runner_->BelongsToCurrentThread());
392 // Queue header.
393 std::vector<uint32> header;
394 header.push_back(message->command);
395 header.push_back(message->arg0);
396 header.push_back(message->arg1);
397 bool append_zero = true;
398 if (message->body.empty())
399 append_zero = false;
400 if (message->command == AdbMessage::kCommandAUTH &&
401 message->arg0 == AdbMessage::kAuthSignature)
402 append_zero = false;
403 if (message->command == AdbMessage::kCommandWRTE)
404 append_zero = false;
406 size_t body_length = message->body.length() + (append_zero ? 1 : 0);
407 header.push_back(body_length);
408 header.push_back(Checksum(message->body));
409 header.push_back(message->command ^ 0xffffffff);
410 scoped_refptr<net::IOBufferWithSize> header_buffer =
411 new net::IOBufferWithSize(kHeaderSize);
412 memcpy(header_buffer.get()->data(), &header[0], kHeaderSize);
413 outgoing_queue_.push(header_buffer);
415 // Queue body.
416 if (!message->body.empty()) {
417 scoped_refptr<net::IOBufferWithSize> body_buffer =
418 new net::IOBufferWithSize(body_length);
419 memcpy(body_buffer->data(), message->body.data(), message->body.length());
420 if (append_zero)
421 body_buffer->data()[body_length - 1] = 0;
422 outgoing_queue_.push(body_buffer);
423 if (zero_mask_ && (body_length & zero_mask_) == 0) {
424 // Send a zero length packet.
425 outgoing_queue_.push(new net::IOBufferWithSize(0));
428 ProcessOutgoing();
431 void AndroidUsbDevice::ProcessOutgoing() {
432 DCHECK(task_runner_->BelongsToCurrentThread());
434 if (outgoing_queue_.empty() || !usb_handle_.get())
435 return;
437 BulkMessage message = outgoing_queue_.front();
438 outgoing_queue_.pop();
439 DumpMessage(true, message->data(), message->size());
441 usb_handle_->GenericTransfer(
442 device::USB_DIRECTION_OUTBOUND, outbound_address_, message,
443 message->size(), kUsbTimeout,
444 base::Bind(&AndroidUsbDevice::OutgoingMessageSent,
445 weak_factory_.GetWeakPtr()));
448 void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status,
449 scoped_refptr<net::IOBuffer> buffer,
450 size_t result) {
451 if (status != device::USB_TRANSFER_COMPLETED) {
452 return;
455 task_runner_->PostTask(FROM_HERE,
456 base::Bind(&AndroidUsbDevice::ProcessOutgoing, this));
459 void AndroidUsbDevice::ReadHeader() {
460 DCHECK(task_runner_->BelongsToCurrentThread());
462 if (!usb_handle_.get()) {
463 return;
466 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize);
467 usb_handle_->GenericTransfer(
468 device::USB_DIRECTION_INBOUND, inbound_address_, buffer, kHeaderSize,
469 kUsbTimeout,
470 base::Bind(&AndroidUsbDevice::ParseHeader, weak_factory_.GetWeakPtr()));
473 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
474 scoped_refptr<net::IOBuffer> buffer,
475 size_t result) {
476 DCHECK(task_runner_->BelongsToCurrentThread());
478 if (status == device::USB_TRANSFER_TIMEOUT) {
479 task_runner_->PostTask(FROM_HERE,
480 base::Bind(&AndroidUsbDevice::ReadHeader, this));
481 return;
484 if (status != device::USB_TRANSFER_COMPLETED || result != kHeaderSize) {
485 TransferError(status);
486 return;
489 DumpMessage(false, buffer->data(), result);
490 std::vector<uint32> header(6);
491 memcpy(&header[0], buffer->data(), result);
492 scoped_ptr<AdbMessage> message(
493 new AdbMessage(header[0], header[1], header[2], ""));
494 uint32 data_length = header[3];
495 uint32 data_check = header[4];
496 uint32 magic = header[5];
497 if ((message->command ^ 0xffffffff) != magic) {
498 TransferError(device::USB_TRANSFER_ERROR);
499 return;
502 if (data_length == 0) {
503 task_runner_->PostTask(FROM_HERE,
504 base::Bind(&AndroidUsbDevice::HandleIncoming, this,
505 base::Passed(&message)));
506 } else {
507 task_runner_->PostTask(
508 FROM_HERE, base::Bind(&AndroidUsbDevice::ReadBody, this,
509 base::Passed(&message), data_length, data_check));
513 void AndroidUsbDevice::ReadBody(scoped_ptr<AdbMessage> message,
514 uint32 data_length,
515 uint32 data_check) {
516 DCHECK(task_runner_->BelongsToCurrentThread());
518 if (!usb_handle_.get()) {
519 return;
522 scoped_refptr<net::IOBuffer> buffer =
523 new net::IOBuffer(static_cast<size_t>(data_length));
524 usb_handle_->GenericTransfer(
525 device::USB_DIRECTION_INBOUND, inbound_address_, buffer, data_length,
526 kUsbTimeout,
527 base::Bind(&AndroidUsbDevice::ParseBody, weak_factory_.GetWeakPtr(),
528 base::Passed(&message), data_length, data_check));
531 void AndroidUsbDevice::ParseBody(scoped_ptr<AdbMessage> message,
532 uint32 data_length,
533 uint32 data_check,
534 UsbTransferStatus status,
535 scoped_refptr<net::IOBuffer> buffer,
536 size_t result) {
537 DCHECK(task_runner_->BelongsToCurrentThread());
539 if (status == device::USB_TRANSFER_TIMEOUT) {
540 task_runner_->PostTask(
541 FROM_HERE, base::Bind(&AndroidUsbDevice::ReadBody, this,
542 base::Passed(&message), data_length, data_check));
543 return;
546 if (status != device::USB_TRANSFER_COMPLETED ||
547 static_cast<uint32>(result) != data_length) {
548 TransferError(status);
549 return;
552 DumpMessage(false, buffer->data(), data_length);
553 message->body = std::string(buffer->data(), result);
554 if (Checksum(message->body) != data_check) {
555 TransferError(device::USB_TRANSFER_ERROR);
556 return;
559 task_runner_->PostTask(FROM_HERE,
560 base::Bind(&AndroidUsbDevice::HandleIncoming, this,
561 base::Passed(&message)));
564 void AndroidUsbDevice::HandleIncoming(scoped_ptr<AdbMessage> message) {
565 DCHECK(task_runner_->BelongsToCurrentThread());
567 switch (message->command) {
568 case AdbMessage::kCommandAUTH:
570 DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken));
571 if (signature_sent_) {
572 Queue(make_scoped_ptr(new AdbMessage(
573 AdbMessage::kCommandAUTH,
574 AdbMessage::kAuthRSAPublicKey, 0,
575 AndroidRSAPublicKey(rsa_key_.get()))));
576 } else {
577 signature_sent_ = true;
578 std::string signature = AndroidRSASign(rsa_key_.get(), message->body);
579 if (!signature.empty()) {
580 Queue(make_scoped_ptr(new AdbMessage(AdbMessage::kCommandAUTH,
581 AdbMessage::kAuthSignature, 0,
582 signature)));
583 } else {
584 Queue(make_scoped_ptr(new AdbMessage(
585 AdbMessage::kCommandAUTH,
586 AdbMessage::kAuthRSAPublicKey, 0,
587 AndroidRSAPublicKey(rsa_key_.get()))));
591 break;
592 case AdbMessage::kCommandCNXN:
594 is_connected_ = true;
595 PendingMessages pending;
596 pending.swap(pending_messages_);
597 for (PendingMessages::iterator it = pending.begin();
598 it != pending.end(); ++it) {
599 Queue(make_scoped_ptr(*it));
602 break;
603 case AdbMessage::kCommandOKAY:
604 case AdbMessage::kCommandWRTE:
605 case AdbMessage::kCommandCLSE:
607 AndroidUsbSockets::iterator it = sockets_.find(message->arg1);
608 if (it != sockets_.end())
609 it->second->HandleIncoming(message.Pass());
611 break;
612 default:
613 break;
615 ReadHeader();
618 void AndroidUsbDevice::TransferError(UsbTransferStatus status) {
619 DCHECK(task_runner_->BelongsToCurrentThread());
621 Terminate();
624 void AndroidUsbDevice::TerminateIfReleased(
625 scoped_refptr<UsbDeviceHandle> usb_handle) {
626 DCHECK_CURRENTLY_ON(BrowserThread::UI);
627 if (usb_handle->GetDevice().get()) {
628 return;
631 task_runner_->PostTask(FROM_HERE,
632 base::Bind(&AndroidUsbDevice::Terminate, this));
635 void AndroidUsbDevice::Terminate() {
636 DCHECK(task_runner_->BelongsToCurrentThread());
638 std::vector<AndroidUsbDevice*>::iterator it =
639 std::find(g_devices.Get().begin(), g_devices.Get().end(), this);
640 if (it != g_devices.Get().end())
641 g_devices.Get().erase(it);
643 if (!usb_handle_.get())
644 return;
646 // Make sure we zero-out handle so that closing connections did not open
647 // new connections.
648 scoped_refptr<UsbDeviceHandle> usb_handle = usb_handle_;
649 usb_handle_ = NULL;
651 // Iterate over copy.
652 AndroidUsbSockets sockets(sockets_);
653 for (AndroidUsbSockets::iterator it = sockets.begin();
654 it != sockets.end(); ++it) {
655 it->second->Terminated(true);
657 DCHECK(sockets_.empty());
659 BrowserThread::PostTask(
660 BrowserThread::UI, FROM_HERE,
661 base::Bind(&ReleaseInterface, usb_handle, interface_id_));
664 void AndroidUsbDevice::SocketDeleted(uint32 socket_id) {
665 DCHECK(task_runner_->BelongsToCurrentThread());
667 sockets_.erase(socket_id);