Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / devtools / android_device.cc
blob7662f83cc2c411c565ef8ec52f454ddf81b7e860
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;
20 namespace {
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;
35 #endif
38 // AdbDeviceImpl --------------------------------------------------------------
40 class AdbDeviceImpl : public AndroidDevice {
41 public:
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;
47 private:
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 {
72 public:
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;
78 private:
79 void OnOpenSocket(const SocketCallback& callback,
80 net::StreamSocket* socket,
81 int result);
82 void OpenedForCommand(const CommandCallback& callback,
83 net::StreamSocket* socket,
84 int result);
85 void OnRead(net::StreamSocket* socket,
86 scoped_refptr<net::IOBuffer> buffer,
87 const std::string& data,
88 const CommandCallback& callback,
89 int result);
91 virtual ~UsbDeviceImpl() {}
92 scoped_refptr<AndroidUsbDevice> device_;
96 UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device)
97 : AndroidDevice(device->serial(), device->is_connected()),
98 device_(device) {
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,
117 callback, socket));
118 if (result != net::ERR_IO_PENDING)
119 callback.Run(result, NULL);
122 void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback,
123 net::StreamSocket* socket,
124 int result) {
125 callback.Run(result, result == net::OK ? socket : NULL);
128 void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback,
129 net::StreamSocket* socket,
130 int result) {
131 if (result != net::OK) {
132 callback.Run(result, std::string());
133 return;
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,
147 int result) {
148 if (result <= 0) {
149 callback.Run(result, result == 0 ? data : std::string());
150 delete socket;
151 return;
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 {
165 public:
166 virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
167 private:
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,
183 this, callback));
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,
196 int result_code,
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,
213 callback, result));
216 // UsbDeviceProvider -------------------------------------------
218 class UsbDeviceProvider : public AndroidDeviceProvider {
219 public:
220 explicit UsbDeviceProvider(Profile* profile);
222 virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
223 private:
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,
244 this, callback));
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,
265 callback, result));
268 } // namespace
270 // AndroidDevice -------------------------------------------
272 AndroidDevice::AndroidDevice(const std::string& serial, bool is_connected)
273 : serial_(serial),
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,
282 request, callback));
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,
290 request, callback));
293 AndroidDevice::~AndroidDevice() {
296 void AndroidDevice::OnHttpSocketOpened(
297 const std::string& request,
298 const CommandCallback& callback,
299 int result,
300 net::StreamSocket* socket) {
301 if (result != net::OK) {
302 callback.Run(result, std::string());
303 return;
305 AdbClientSocket::HttpQuery(socket, request, callback);
308 void AndroidDevice::OnHttpSocketOpened2(
309 const std::string& request,
310 const SocketCallback& callback,
311 int result,
312 net::StreamSocket* socket) {
313 if (result != net::OK) {
314 callback.Run(result, NULL);
315 return;
317 AdbClientSocket::HttpQuery(socket, request, callback);
320 // AdbCountDevicesCommand -----------------------------------------------------
321 class AdbCountDevicesCommand : public base::RefCountedThreadSafe<
322 AdbCountDevicesCommand, BrowserThread::DeleteOnUIThread> {
323 public:
324 typedef base::Callback<void(int)> Callback;
326 AdbCountDevicesCommand(
327 scoped_refptr<RefCountedAdbThread> adb_thread,
328 const Callback& callback);
330 private:
331 friend struct BrowserThread::DeleteOnThread<
332 BrowserThread::UI>;
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_;
341 Callback callback_;
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,
351 this));
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(
366 int result,
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() {
390 // static
391 void AndroidDeviceProvider::RunCallbackOnUIThread(
392 const QueryDevicesCallback& callback,
393 const AndroidDevices& result) {
394 callback.Run(result);
397 // static
398 void AndroidDeviceProvider::CountDevices(bool discover_usb_devices,
399 const base::Callback<void(int)>& callback) {
400 if (discover_usb_devices) {
401 AndroidUsbDevice::CountDevices(callback);
402 return;
405 new AdbCountDevicesCommand(RefCountedAdbThread::GetInstance(), callback);
408 // static
409 scoped_refptr<AndroidDeviceProvider>
410 AndroidDeviceProvider::GetUsbDeviceProvider(Profile* profile) {
411 return new UsbDeviceProvider(profile);
414 // static
415 scoped_refptr<AndroidDeviceProvider>
416 AndroidDeviceProvider::GetAdbDeviceProvider() {
417 return new AdbDeviceProvider();
421 #if defined(DEBUG_DEVTOOLS)
422 class SelfAsDevice : public AndroidDevice {
423 public:
424 SelfAsDevice();
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;
429 private:
430 void RunCommandCallback(const CommandCallback& callback,
431 const std::string& response,
432 int result);
434 void RunSocketCallback(const SocketCallback& callback,
435 net::StreamSocket* socket,
436 int result);
437 virtual ~SelfAsDevice() {}
440 SelfAsDevice::SelfAsDevice()
441 : AndroidDevice("local", true)
444 void SelfAsDevice::RunCommandCallback(const CommandCallback& callback,
445 const std::string& response,
446 int result) {
447 callback.Run(result, response);
450 void SelfAsDevice::RunSocketCallback(const SocketCallback& callback,
451 net::StreamSocket* socket,
452 int result) {
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,
469 response, 0));
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,
483 socket));
486 class SelfAsDeviceProvider : public AndroidDeviceProvider {
487 public:
488 virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
489 private:
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,
500 callback, result));
503 // static
504 scoped_refptr<AndroidDeviceProvider>
505 AndroidDeviceProvider::GetSelfAsDeviceProvider() {
506 return new SelfAsDeviceProvider();
508 #endif