1 // Copyright 2013 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/android_device.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/threading/thread.h"
11 #include "chrome/browser/devtools/adb/android_rsa.h"
12 #include "chrome/browser/devtools/adb/android_usb_device.h"
13 #include "chrome/browser/devtools/adb_client_socket.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/net_util.h"
16 #include "net/socket/tcp_client_socket.h"
18 using content::BrowserThread
;
22 const char kHostTransportCommand
[] = "host:transport:%s|%s";
23 const char kHostDevicesCommand
[] = "host:devices";
24 const char kLocalAbstractCommand
[] = "localabstract:%s";
26 const int kAdbPort
= 5037;
27 const int kBufferSize
= 16 * 1024;
29 #if defined(DEBUG_DEVTOOLS)
30 const char kDeviceModelCommand
[] = "shell:getprop ro.product.model";
31 const char kOpenedUnixSocketsCommand
[] = "shell:cat /proc/net/unix";
32 const char kLocalChrome
[] = "Local Chrome";
33 const char kLocalhost
[] = "127.0.0.1";
34 const int kTcpPort
= 9222;
38 // AdbDeviceImpl --------------------------------------------------------------
40 class AdbDeviceImpl
: public AndroidDevice
{
42 AdbDeviceImpl(const std::string
& serial
, bool is_connected
);
43 virtual void RunCommand(const std::string
& command
,
44 const CommandCallback
& callback
) OVERRIDE
;
45 virtual void OpenSocket(const std::string
& name
,
46 const SocketCallback
& callback
) OVERRIDE
;
48 virtual ~AdbDeviceImpl() {}
51 AdbDeviceImpl::AdbDeviceImpl(const std::string
& serial
, bool is_connected
)
52 : AndroidDevice(serial
, is_connected
) {
55 void AdbDeviceImpl::RunCommand(const std::string
& command
,
56 const CommandCallback
& callback
) {
57 std::string query
= base::StringPrintf(kHostTransportCommand
,
58 serial().c_str(), command
.c_str());
59 AdbClientSocket::AdbQuery(kAdbPort
, query
, callback
);
62 void AdbDeviceImpl::OpenSocket(const std::string
& name
,
63 const SocketCallback
& callback
) {
64 std::string socket_name
=
65 base::StringPrintf(kLocalAbstractCommand
, name
.c_str());
66 AdbClientSocket::TransportQuery(kAdbPort
, serial(), socket_name
, callback
);
69 // UsbDeviceImpl --------------------------------------------------------------
71 class UsbDeviceImpl
: public AndroidDevice
{
73 explicit UsbDeviceImpl(AndroidUsbDevice
* device
);
74 virtual void RunCommand(const std::string
& command
,
75 const CommandCallback
& callback
) OVERRIDE
;
76 virtual void OpenSocket(const std::string
& name
,
77 const SocketCallback
& callback
) OVERRIDE
;
79 void OnOpenSocket(const SocketCallback
& callback
,
80 net::StreamSocket
* socket
,
82 void OpenedForCommand(const CommandCallback
& callback
,
83 net::StreamSocket
* socket
,
85 void OnRead(net::StreamSocket
* socket
,
86 scoped_refptr
<net::IOBuffer
> buffer
,
87 const std::string
& data
,
88 const CommandCallback
& callback
,
91 virtual ~UsbDeviceImpl() {}
92 scoped_refptr
<AndroidUsbDevice
> device_
;
96 UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice
* device
)
97 : AndroidDevice(device
->serial(), device
->is_connected()),
99 device_
->InitOnCallerThread();
102 void UsbDeviceImpl::RunCommand(const std::string
& command
,
103 const CommandCallback
& callback
) {
104 net::StreamSocket
* socket
= device_
->CreateSocket(command
);
105 int result
= socket
->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand
,
106 this, callback
, socket
));
107 if (result
!= net::ERR_IO_PENDING
)
108 callback
.Run(result
, std::string());
111 void UsbDeviceImpl::OpenSocket(const std::string
& name
,
112 const SocketCallback
& callback
) {
113 std::string socket_name
=
114 base::StringPrintf(kLocalAbstractCommand
, name
.c_str());
115 net::StreamSocket
* socket
= device_
->CreateSocket(socket_name
);
116 int result
= socket
->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket
, this,
118 if (result
!= net::ERR_IO_PENDING
)
119 callback
.Run(result
, NULL
);
122 void UsbDeviceImpl::OnOpenSocket(const SocketCallback
& callback
,
123 net::StreamSocket
* socket
,
125 callback
.Run(result
, result
== net::OK
? socket
: NULL
);
128 void UsbDeviceImpl::OpenedForCommand(const CommandCallback
& callback
,
129 net::StreamSocket
* socket
,
131 if (result
!= net::OK
) {
132 callback
.Run(result
, std::string());
135 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(kBufferSize
);
136 result
= socket
->Read(buffer
, kBufferSize
,
137 base::Bind(&UsbDeviceImpl::OnRead
, this,
138 socket
, buffer
, std::string(), callback
));
139 if (result
!= net::ERR_IO_PENDING
)
140 OnRead(socket
, buffer
, std::string(), callback
, result
);
143 void UsbDeviceImpl::OnRead(net::StreamSocket
* socket
,
144 scoped_refptr
<net::IOBuffer
> buffer
,
145 const std::string
& data
,
146 const CommandCallback
& callback
,
149 callback
.Run(result
, result
== 0 ? data
: std::string());
154 std::string new_data
= data
+ std::string(buffer
->data(), result
);
155 result
= socket
->Read(buffer
, kBufferSize
,
156 base::Bind(&UsbDeviceImpl::OnRead
, this,
157 socket
, buffer
, new_data
, callback
));
158 if (result
!= net::ERR_IO_PENDING
)
159 OnRead(socket
, buffer
, new_data
, callback
, result
);
162 // AdbDeviceProvider -------------------------------------------
164 class AdbDeviceProvider
: public AndroidDeviceProvider
{
166 virtual void QueryDevices(const QueryDevicesCallback
& callback
) OVERRIDE
;
168 void QueryDevicesOnAdbThread(const QueryDevicesCallback
& callback
);
169 void ReceivedAdbDevices(const QueryDevicesCallback
& callback
, int result
,
170 const std::string
& response
);
172 virtual ~AdbDeviceProvider();
175 AdbDeviceProvider::~AdbDeviceProvider() {
178 void AdbDeviceProvider::QueryDevices(const QueryDevicesCallback
& callback
) {
179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
181 adb_thread_
->message_loop()->PostTask(
182 FROM_HERE
, base::Bind(&AdbDeviceProvider::QueryDevicesOnAdbThread
,
186 void AdbDeviceProvider::QueryDevicesOnAdbThread(
187 const QueryDevicesCallback
& callback
) {
188 DCHECK_EQ(adb_thread_
->message_loop(), base::MessageLoop::current());
190 AdbClientSocket::AdbQuery(
191 kAdbPort
, kHostDevicesCommand
,
192 base::Bind(&AdbDeviceProvider::ReceivedAdbDevices
, this, callback
));
195 void AdbDeviceProvider::ReceivedAdbDevices(const QueryDevicesCallback
& callback
,
197 const std::string
& response
) {
198 DCHECK_EQ(adb_thread_
->message_loop(), base::MessageLoop::current());
200 AndroidDevices result
;
202 std::vector
<std::string
> serials
;
203 Tokenize(response
, "\n", &serials
);
204 for (size_t i
= 0; i
< serials
.size(); ++i
) {
205 std::vector
<std::string
> tokens
;
206 Tokenize(serials
[i
], "\t ", &tokens
);
207 bool offline
= tokens
.size() > 1 && tokens
[1] == "offline";
208 result
.push_back(new AdbDeviceImpl(tokens
[0], !offline
));
211 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
212 base::Bind(&AdbDeviceProvider::RunCallbackOnUIThread
,
216 // UsbDeviceProvider -------------------------------------------
218 class UsbDeviceProvider
: public AndroidDeviceProvider
{
220 explicit UsbDeviceProvider(Profile
* profile
);
222 virtual void QueryDevices(const QueryDevicesCallback
& callback
) OVERRIDE
;
224 virtual ~UsbDeviceProvider();
225 void WrapDevicesOnAdbThread(const QueryDevicesCallback
& callback
,
226 const AndroidUsbDevices
& devices
);
227 void EnumeratedDevices(const QueryDevicesCallback
& callback
,
228 const AndroidUsbDevices
& devices
);
230 scoped_ptr
<crypto::RSAPrivateKey
> rsa_key_
;
233 UsbDeviceProvider::UsbDeviceProvider(Profile
* profile
){
234 rsa_key_
.reset(AndroidRSAPrivateKey(profile
));
237 UsbDeviceProvider::~UsbDeviceProvider() {
240 void UsbDeviceProvider::QueryDevices(const QueryDevicesCallback
& callback
) {
241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
242 AndroidUsbDevice::Enumerate(rsa_key_
.get(),
243 base::Bind(&UsbDeviceProvider::EnumeratedDevices
,
247 void UsbDeviceProvider::EnumeratedDevices(const QueryDevicesCallback
& callback
,
248 const AndroidUsbDevices
& devices
) {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
250 adb_thread_
->message_loop()->PostTask(FROM_HERE
,
251 base::Bind(&UsbDeviceProvider::WrapDevicesOnAdbThread
,
252 this, callback
, devices
));
255 void UsbDeviceProvider::WrapDevicesOnAdbThread(
256 const QueryDevicesCallback
& callback
,const AndroidUsbDevices
& devices
) {
257 DCHECK_EQ(adb_thread_
->message_loop(), base::MessageLoop::current());
258 AndroidDevices result
;
259 for (AndroidUsbDevices::const_iterator it
= devices
.begin();
260 it
!= devices
.end(); ++it
)
261 result
.push_back(new UsbDeviceImpl(*it
));
263 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
264 base::Bind(&UsbDeviceProvider::RunCallbackOnUIThread
,
270 // AndroidDevice -------------------------------------------
272 AndroidDevice::AndroidDevice(const std::string
& serial
, bool is_connected
)
274 is_connected_(is_connected
) {
277 void AndroidDevice::HttpQuery(
278 const std::string
& la_name
,
279 const std::string
& request
,
280 const CommandCallback
& callback
) {
281 OpenSocket(la_name
, base::Bind(&AndroidDevice::OnHttpSocketOpened
, this,
285 void AndroidDevice::HttpUpgrade(
286 const std::string
& la_name
,
287 const std::string
& request
,
288 const SocketCallback
& callback
) {
289 OpenSocket(la_name
, base::Bind(&AndroidDevice::OnHttpSocketOpened2
, this,
293 AndroidDevice::~AndroidDevice() {
296 void AndroidDevice::OnHttpSocketOpened(
297 const std::string
& request
,
298 const CommandCallback
& callback
,
300 net::StreamSocket
* socket
) {
301 if (result
!= net::OK
) {
302 callback
.Run(result
, std::string());
305 AdbClientSocket::HttpQuery(socket
, request
, callback
);
308 void AndroidDevice::OnHttpSocketOpened2(
309 const std::string
& request
,
310 const SocketCallback
& callback
,
312 net::StreamSocket
* socket
) {
313 if (result
!= net::OK
) {
314 callback
.Run(result
, NULL
);
317 AdbClientSocket::HttpQuery(socket
, request
, callback
);
320 // AdbCountDevicesCommand -----------------------------------------------------
321 class AdbCountDevicesCommand
: public base::RefCountedThreadSafe
<
322 AdbCountDevicesCommand
, BrowserThread::DeleteOnUIThread
> {
324 typedef base::Callback
<void(int)> Callback
;
326 AdbCountDevicesCommand(
327 scoped_refptr
<RefCountedAdbThread
> adb_thread
,
328 const Callback
& callback
);
331 friend struct BrowserThread::DeleteOnThread
<
333 friend class base::DeleteHelper
<AdbCountDevicesCommand
>;
335 virtual ~AdbCountDevicesCommand();
336 void RequestAdbDeviceCount();
337 void ReceivedAdbDeviceCount(int result
, const std::string
& response
);
338 void Respond(int count
);
340 scoped_refptr
<RefCountedAdbThread
> adb_thread_
;
344 AdbCountDevicesCommand::AdbCountDevicesCommand(
345 scoped_refptr
<RefCountedAdbThread
> adb_thread
,
346 const Callback
& callback
)
347 : adb_thread_(adb_thread
),
348 callback_(callback
) {
349 adb_thread_
->message_loop()->PostTask(
350 FROM_HERE
, base::Bind(&AdbCountDevicesCommand::RequestAdbDeviceCount
,
354 AdbCountDevicesCommand::~AdbCountDevicesCommand() {
355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
358 void AdbCountDevicesCommand::RequestAdbDeviceCount() {
359 DCHECK_EQ(adb_thread_
->message_loop(), base::MessageLoop::current());
360 AdbClientSocket::AdbQuery(
361 kAdbPort
, kHostDevicesCommand
,
362 base::Bind(&AdbCountDevicesCommand::ReceivedAdbDeviceCount
, this));
365 void AdbCountDevicesCommand::ReceivedAdbDeviceCount(
367 const std::string
& response
) {
368 DCHECK_EQ(adb_thread_
->message_loop(), base::MessageLoop::current());
369 std::vector
<std::string
> serials
;
370 Tokenize(response
, "\n", &serials
);
371 BrowserThread::PostTask(
372 BrowserThread::UI
, FROM_HERE
,
373 base::Bind(&AdbCountDevicesCommand::Respond
, this, serials
.size()));
376 void AdbCountDevicesCommand::Respond(int count
) {
377 callback_
.Run(count
);
380 // AndroidDeviceProvider ---------------------------------------------------
382 AndroidDeviceProvider::AndroidDeviceProvider()
383 : adb_thread_(RefCountedAdbThread::GetInstance()) {
387 AndroidDeviceProvider::~AndroidDeviceProvider() {
391 void AndroidDeviceProvider::RunCallbackOnUIThread(
392 const QueryDevicesCallback
& callback
,
393 const AndroidDevices
& result
) {
394 callback
.Run(result
);
398 void AndroidDeviceProvider::CountDevices(bool discover_usb_devices
,
399 const base::Callback
<void(int)>& callback
) {
400 if (discover_usb_devices
) {
401 AndroidUsbDevice::CountDevices(callback
);
405 new AdbCountDevicesCommand(RefCountedAdbThread::GetInstance(), callback
);
409 scoped_refptr
<AndroidDeviceProvider
>
410 AndroidDeviceProvider::GetUsbDeviceProvider(Profile
* profile
) {
411 return new UsbDeviceProvider(profile
);
415 scoped_refptr
<AndroidDeviceProvider
>
416 AndroidDeviceProvider::GetAdbDeviceProvider() {
417 return new AdbDeviceProvider();
421 #if defined(DEBUG_DEVTOOLS)
422 class SelfAsDevice
: public AndroidDevice
{
425 virtual void RunCommand(const std::string
& command
,
426 const CommandCallback
& callback
) OVERRIDE
;
427 virtual void OpenSocket(const std::string
& socket_name
,
428 const SocketCallback
& callback
) OVERRIDE
;
430 void RunCommandCallback(const CommandCallback
& callback
,
431 const std::string
& response
,
434 void RunSocketCallback(const SocketCallback
& callback
,
435 net::StreamSocket
* socket
,
437 virtual ~SelfAsDevice() {}
440 SelfAsDevice::SelfAsDevice()
441 : AndroidDevice("local", true)
444 void SelfAsDevice::RunCommandCallback(const CommandCallback
& callback
,
445 const std::string
& response
,
447 callback
.Run(result
, response
);
450 void SelfAsDevice::RunSocketCallback(const SocketCallback
& callback
,
451 net::StreamSocket
* socket
,
453 callback
.Run(result
, socket
);
456 void SelfAsDevice::RunCommand(const std::string
& command
,
457 const CommandCallback
& callback
) {
458 std::string response
;
459 if (command
== kDeviceModelCommand
) {
460 response
= kLocalChrome
;
461 } else if (command
== kOpenedUnixSocketsCommand
) {
462 response
= "Num RefCount Protocol Flags Type St Inode Path\n"
463 "00000000: 00000002 00000000"
464 " 00010000 0001 01 20894 @chrome_devtools_remote\n";
467 base::MessageLoop::current()->PostTask(FROM_HERE
,
468 base::Bind(&SelfAsDevice::RunCommandCallback
, this, callback
,
472 void SelfAsDevice::OpenSocket(const std::string
& socket_name
,
473 const SocketCallback
& callback
) {
474 // Use plain socket for remote debugging on Desktop (debugging purposes).
475 net::IPAddressNumber ip_number
;
476 net::ParseIPLiteralToNumber(kLocalhost
, &ip_number
);
478 net::AddressList address_list
=
479 net::AddressList::CreateFromIPAddress(ip_number
, kTcpPort
);
480 net::TCPClientSocket
* socket
= new net::TCPClientSocket(
481 address_list
, NULL
, net::NetLog::Source());
482 socket
->Connect(base::Bind(&SelfAsDevice::RunSocketCallback
, this, callback
,
486 class SelfAsDeviceProvider
: public AndroidDeviceProvider
{
488 virtual void QueryDevices(const QueryDevicesCallback
& callback
) OVERRIDE
;
490 virtual ~SelfAsDeviceProvider(){}
493 void SelfAsDeviceProvider::QueryDevices(const QueryDevicesCallback
& callback
) {
494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
495 AndroidDevices result
;
496 result
.push_back(new SelfAsDevice());
498 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
499 base::Bind(&SelfAsDeviceProvider::RunCallbackOnUIThread
,
504 scoped_refptr
<AndroidDeviceProvider
>
505 AndroidDeviceProvider::GetSelfAsDeviceProvider() {
506 return new SelfAsDeviceProvider();