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/usb_device_provider.h"
7 #include "base/strings/stringprintf.h"
8 #include "chrome/browser/devtools/device/adb/adb_device_info_query.h"
9 #include "chrome/browser/devtools/device/usb/android_rsa.h"
10 #include "chrome/browser/devtools/device/usb/android_usb_device.h"
11 #include "crypto/rsa_private_key.h"
12 #include "net/base/net_errors.h"
13 #include "net/socket/stream_socket.h"
17 const char kLocalAbstractCommand[] = "localabstract:%s";
19 const int kBufferSize = 16 * 1024;
21 void OnOpenSocket(const UsbDeviceProvider::SocketCallback& callback,
22 net::StreamSocket* socket,
24 callback.Run(result, result == net::OK ? socket : NULL);
27 void OnRead(net::StreamSocket* socket,
28 scoped_refptr<net::IOBuffer> buffer,
29 const std::string& data,
30 const UsbDeviceProvider::CommandCallback& callback,
33 callback.Run(result, result == 0 ? data : std::string());
38 std::string new_data = data + std::string(buffer->data(), result);
42 base::Bind(&OnRead, socket, buffer, new_data, callback));
43 if (result != net::ERR_IO_PENDING)
44 OnRead(socket, buffer, new_data, callback, result);
47 void OpenedForCommand(const UsbDeviceProvider::CommandCallback& callback,
48 net::StreamSocket* socket,
50 if (result != net::OK) {
51 callback.Run(result, std::string());
54 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
55 result = socket->Read(
58 base::Bind(&OnRead, socket, buffer, std::string(), callback));
59 if (result != net::ERR_IO_PENDING)
60 OnRead(socket, buffer, std::string(), callback, result);
63 void RunCommand(scoped_refptr<AndroidUsbDevice> device,
64 const std::string& command,
65 const UsbDeviceProvider::CommandCallback& callback) {
66 net::StreamSocket* socket = device->CreateSocket(command);
68 callback.Run(net::ERR_CONNECTION_FAILED, std::string());
71 int result = socket->Connect(base::Bind(&OpenedForCommand, callback, socket));
72 if (result != net::ERR_IO_PENDING)
73 callback.Run(result, std::string());
79 void UsbDeviceProvider::CountDevices(
80 const base::Callback<void(int)>& callback) {
81 AndroidUsbDevice::CountDevices(callback);
84 UsbDeviceProvider::UsbDeviceProvider(Profile* profile){
85 rsa_key_.reset(AndroidRSAPrivateKey(profile));
88 void UsbDeviceProvider::QueryDevices(const SerialsCallback& callback) {
89 AndroidUsbDevice::Enumerate(
91 base::Bind(&UsbDeviceProvider::EnumeratedDevices, this, callback));
94 void UsbDeviceProvider::QueryDeviceInfo(const std::string& serial,
95 const DeviceInfoCallback& callback) {
96 UsbDeviceMap::iterator it = device_map_.find(serial);
97 if (it == device_map_.end() || !it->second->is_connected()) {
98 AndroidDeviceManager::DeviceInfo offline_info;
99 callback.Run(offline_info);
102 AdbDeviceInfoQuery::Start(base::Bind(&RunCommand, it->second), callback);
105 void UsbDeviceProvider::OpenSocket(const std::string& serial,
106 const std::string& name,
107 const SocketCallback& callback) {
108 UsbDeviceMap::iterator it = device_map_.find(serial);
109 if (it == device_map_.end()) {
110 callback.Run(net::ERR_CONNECTION_FAILED, NULL);
113 std::string socket_name =
114 base::StringPrintf(kLocalAbstractCommand, name.c_str());
115 net::StreamSocket* socket = it->second->CreateSocket(socket_name);
117 callback.Run(net::ERR_CONNECTION_FAILED, NULL);
120 int result = socket->Connect(base::Bind(&OnOpenSocket, callback, socket));
121 if (result != net::ERR_IO_PENDING)
122 callback.Run(result, NULL);
125 void UsbDeviceProvider::ReleaseDevice(const std::string& serial) {
126 device_map_.erase(serial);
129 UsbDeviceProvider::~UsbDeviceProvider() {
132 void UsbDeviceProvider::EnumeratedDevices(const SerialsCallback& callback,
133 const AndroidUsbDevices& devices) {
134 std::vector<std::string> result;
136 for (AndroidUsbDevices::const_iterator it = devices.begin();
137 it != devices.end(); ++it) {
138 result.push_back((*it)->serial());
139 device_map_[(*it)->serial()] = *it;
140 (*it)->InitOnCallerThread();
142 callback.Run(result);