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/usb/android_rsa.h"
9 #include "chrome/browser/devtools/device/usb/android_usb_device.h"
10 #include "crypto/rsa_private_key.h"
11 #include "net/base/net_errors.h"
12 #include "net/socket/stream_socket.h"
16 const char kLocalAbstractCommand
[] = "localabstract:%s";
18 const int kBufferSize
= 16 * 1024;
20 void OnOpenSocket(const UsbDeviceProvider::SocketCallback
& callback
,
21 net::StreamSocket
* socket_raw
,
23 scoped_ptr
<net::StreamSocket
> socket(socket_raw
);
24 if (result
!= net::OK
)
26 callback
.Run(result
, socket
.Pass());
29 void OnRead(net::StreamSocket
* socket
,
30 scoped_refptr
<net::IOBuffer
> buffer
,
31 const std::string
& data
,
32 const UsbDeviceProvider::CommandCallback
& callback
,
35 callback
.Run(result
, result
== 0 ? data
: std::string());
40 std::string new_data
= data
+ std::string(buffer
->data(), result
);
42 socket
->Read(buffer
.get(),
44 base::Bind(&OnRead
, socket
, buffer
, new_data
, callback
));
45 if (result
!= net::ERR_IO_PENDING
)
46 OnRead(socket
, buffer
, new_data
, callback
, result
);
49 void OpenedForCommand(const UsbDeviceProvider::CommandCallback
& callback
,
50 net::StreamSocket
* socket
,
52 if (result
!= net::OK
) {
53 callback
.Run(result
, std::string());
56 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(kBufferSize
);
57 result
= socket
->Read(
60 base::Bind(&OnRead
, socket
, buffer
, std::string(), callback
));
61 if (result
!= net::ERR_IO_PENDING
)
62 OnRead(socket
, buffer
, std::string(), callback
, result
);
65 void RunCommand(scoped_refptr
<AndroidUsbDevice
> device
,
66 const std::string
& command
,
67 const UsbDeviceProvider::CommandCallback
& callback
) {
68 net::StreamSocket
* socket
= device
->CreateSocket(command
);
70 callback
.Run(net::ERR_CONNECTION_FAILED
, std::string());
73 int result
= socket
->Connect(
74 base::Bind(&OpenedForCommand
, callback
, socket
));
75 if (result
!= net::ERR_IO_PENDING
)
76 callback
.Run(result
, std::string());
82 void UsbDeviceProvider::CountDevices(
83 const base::Callback
<void(int)>& callback
) {
84 AndroidUsbDevice::CountDevices(callback
);
87 UsbDeviceProvider::UsbDeviceProvider(Profile
* profile
){
88 rsa_key_
.reset(AndroidRSAPrivateKey(profile
));
91 void UsbDeviceProvider::QueryDevices(const SerialsCallback
& callback
) {
92 AndroidUsbDevice::Enumerate(
94 base::Bind(&UsbDeviceProvider::EnumeratedDevices
, this, callback
));
97 void UsbDeviceProvider::QueryDeviceInfo(const std::string
& serial
,
98 const DeviceInfoCallback
& callback
) {
99 UsbDeviceMap::iterator it
= device_map_
.find(serial
);
100 if (it
== device_map_
.end() || !it
->second
->is_connected()) {
101 AndroidDeviceManager::DeviceInfo offline_info
;
102 callback
.Run(offline_info
);
105 AndroidDeviceManager::QueryDeviceInfo(base::Bind(&RunCommand
, it
->second
),
109 void UsbDeviceProvider::OpenSocket(const std::string
& serial
,
110 const std::string
& name
,
111 const SocketCallback
& callback
) {
112 UsbDeviceMap::iterator it
= device_map_
.find(serial
);
113 if (it
== device_map_
.end()) {
114 callback
.Run(net::ERR_CONNECTION_FAILED
,
115 make_scoped_ptr
<net::StreamSocket
>(NULL
));
118 std::string socket_name
=
119 base::StringPrintf(kLocalAbstractCommand
, name
.c_str());
120 net::StreamSocket
* socket
= it
->second
->CreateSocket(socket_name
);
122 callback
.Run(net::ERR_CONNECTION_FAILED
,
123 make_scoped_ptr
<net::StreamSocket
>(NULL
));
126 int result
= socket
->Connect(base::Bind(&OnOpenSocket
, callback
, socket
));
127 if (result
!= net::ERR_IO_PENDING
)
128 callback
.Run(result
, make_scoped_ptr
<net::StreamSocket
>(NULL
));
131 void UsbDeviceProvider::ReleaseDevice(const std::string
& serial
) {
132 device_map_
.erase(serial
);
135 UsbDeviceProvider::~UsbDeviceProvider() {
138 void UsbDeviceProvider::EnumeratedDevices(const SerialsCallback
& callback
,
139 const AndroidUsbDevices
& devices
) {
140 std::vector
<std::string
> result
;
142 for (AndroidUsbDevices::const_iterator it
= devices
.begin();
143 it
!= devices
.end(); ++it
) {
144 result
.push_back((*it
)->serial());
145 device_map_
[(*it
)->serial()] = *it
;
146 (*it
)->InitOnCallerThread();
148 callback
.Run(result
);