- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / devtools / android_device.cc
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.
4
5 #include "chrome/browser/devtools/android_device.h"
6
7 #include "base/strings/string_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/threading/thread.h"
10 #include "chrome/browser/devtools/adb/android_rsa.h"
11 #include "chrome/browser/devtools/adb/android_usb_device.h"
12 #include "chrome/browser/devtools/adb_client_socket.h"
13 #include "net/base/net_errors.h"
14
15 using content::BrowserThread;
16
17 namespace {
18
19 const char kHostTransportCommand[] = "host:transport:%s|%s";
20 const char kHostDevicesCommand[] = "host:devices";
21 const char kLocalAbstractCommand[] = "localabstract:%s";
22
23 const int kAdbPort = 5037;
24 const int kBufferSize = 16 * 1024;
25
26 // AdbDeviceImpl --------------------------------------------------------------
27
28 class AdbDeviceImpl : public AndroidDevice {
29  public:
30   AdbDeviceImpl(const std::string& serial, bool is_connected);
31   virtual void RunCommand(const std::string& command,
32                           const CommandCallback& callback) OVERRIDE;
33   virtual void OpenSocket(const std::string& name,
34                           const SocketCallback& callback) OVERRIDE;
35  private:
36   virtual ~AdbDeviceImpl() {}
37 };
38
39 AdbDeviceImpl::AdbDeviceImpl(const std::string& serial, bool is_connected)
40     : AndroidDevice(serial, is_connected) {
41 }
42
43 void AdbDeviceImpl::RunCommand(const std::string& command,
44                                const CommandCallback& callback) {
45   std::string query = base::StringPrintf(kHostTransportCommand,
46                                          serial().c_str(), command.c_str());
47   AdbClientSocket::AdbQuery(kAdbPort, query, callback);
48 }
49
50 void AdbDeviceImpl::OpenSocket(const std::string& name,
51                                const SocketCallback& callback) {
52   std::string socket_name =
53       base::StringPrintf(kLocalAbstractCommand, name.c_str());
54   AdbClientSocket::TransportQuery(kAdbPort, serial(), socket_name, callback);
55 }
56
57 // UsbDeviceImpl --------------------------------------------------------------
58
59 class UsbDeviceImpl : public AndroidDevice {
60  public:
61   explicit UsbDeviceImpl(AndroidUsbDevice* device);
62   virtual void RunCommand(const std::string& command,
63                           const CommandCallback& callback) OVERRIDE;
64   virtual void OpenSocket(const std::string& name,
65                           const SocketCallback& callback) OVERRIDE;
66  private:
67   void OnOpenSocket(const SocketCallback& callback,
68                     net::StreamSocket* socket,
69                     int result);
70   void OpenedForCommand(const CommandCallback& callback,
71                         net::StreamSocket* socket,
72                         int result);
73   void OnRead(net::StreamSocket* socket,
74               scoped_refptr<net::IOBuffer> buffer,
75               const std::string& data,
76               const CommandCallback& callback,
77               int result);
78
79   virtual ~UsbDeviceImpl() {}
80   scoped_refptr<AndroidUsbDevice> device_;
81 };
82
83
84 UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device)
85     : AndroidDevice(device->serial(), device->is_connected()),
86       device_(device) {
87   device_->InitOnCallerThread();
88 }
89
90 void UsbDeviceImpl::RunCommand(const std::string& command,
91                                const CommandCallback& callback) {
92   net::StreamSocket* socket = device_->CreateSocket(command);
93   int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand,
94                                           this, callback, socket));
95   if (result != net::ERR_IO_PENDING)
96     callback.Run(result, std::string());
97 }
98
99 void UsbDeviceImpl::OpenSocket(const std::string& name,
100                                const SocketCallback& callback) {
101   std::string socket_name =
102       base::StringPrintf(kLocalAbstractCommand, name.c_str());
103   net::StreamSocket* socket = device_->CreateSocket(socket_name);
104   int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this,
105                                           callback, socket));
106   if (result != net::ERR_IO_PENDING)
107     callback.Run(result, NULL);
108 }
109
110 void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback,
111                   net::StreamSocket* socket,
112                   int result) {
113   callback.Run(result, result == net::OK ? socket : NULL);
114 }
115
116 void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback,
117                                      net::StreamSocket* socket,
118                                      int result) {
119   if (result != net::OK) {
120     callback.Run(result, std::string());
121     return;
122   }
123   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
124   result = socket->Read(buffer, kBufferSize,
125                         base::Bind(&UsbDeviceImpl::OnRead, this,
126                                    socket, buffer, std::string(), callback));
127   if (result != net::ERR_IO_PENDING)
128     OnRead(socket, buffer, std::string(), callback, result);
129 }
130
131 void UsbDeviceImpl::OnRead(net::StreamSocket* socket,
132                            scoped_refptr<net::IOBuffer> buffer,
133                            const std::string& data,
134                            const CommandCallback& callback,
135                            int result) {
136   if (result <= 0) {
137     callback.Run(result, result == 0 ? data : std::string());
138     delete socket;
139     return;
140   }
141
142   std::string new_data = data + std::string(buffer->data(), result);
143   result = socket->Read(buffer, kBufferSize,
144                         base::Bind(&UsbDeviceImpl::OnRead, this,
145                                    socket, buffer, new_data, callback));
146   if (result != net::ERR_IO_PENDING)
147     OnRead(socket, buffer, new_data, callback, result);
148 }
149
150 // AdbDeviceProvider -------------------------------------------
151
152 class AdbDeviceProvider: public AndroidDeviceProvider {
153  public:
154   virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
155  private:
156   void QueryDevicesOnAdbThread(const QueryDevicesCallback& callback);
157   void ReceivedAdbDevices(const QueryDevicesCallback& callback, int result,
158                           const std::string& response);
159
160   virtual ~AdbDeviceProvider();
161 };
162
163 AdbDeviceProvider::~AdbDeviceProvider() {
164 }
165
166 void AdbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
167   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168
169   adb_thread_->message_loop()->PostTask(
170         FROM_HERE, base::Bind(&AdbDeviceProvider::QueryDevicesOnAdbThread,
171         this, callback));
172 }
173
174 void AdbDeviceProvider::QueryDevicesOnAdbThread(
175     const QueryDevicesCallback& callback) {
176   DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
177
178   AdbClientSocket::AdbQuery(
179       kAdbPort, kHostDevicesCommand,
180       base::Bind(&AdbDeviceProvider::ReceivedAdbDevices, this, callback));
181 }
182
183 void AdbDeviceProvider::ReceivedAdbDevices(const QueryDevicesCallback& callback,
184                                            int result_code,
185                                            const std::string& response) {
186   DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
187
188   AndroidDevices result;
189
190 #if defined(DEBUG_DEVTOOLS)
191   // For desktop remote debugging.
192   result.push_back(new AdbDeviceImpl("", true));
193 #endif  // defined(DEBUG_DEVTOOLS)
194
195   std::vector<std::string> serials;
196   Tokenize(response, "\n", &serials);
197   for (size_t i = 0; i < serials.size(); ++i) {
198     std::vector<std::string> tokens;
199     Tokenize(serials[i], "\t ", &tokens);
200     bool offline = tokens.size() > 1 && tokens[1] == "offline";
201     result.push_back(new AdbDeviceImpl(tokens[0], !offline));
202   }
203
204   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
205                           base::Bind(&AdbDeviceProvider::RunCallbackOnUIThread,
206                           callback, result));
207 }
208
209 // UsbDeviceProvider -------------------------------------------
210
211 class UsbDeviceProvider: public AndroidDeviceProvider {
212  public:
213   explicit UsbDeviceProvider(Profile* profile);
214
215   virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
216  private:
217   virtual ~UsbDeviceProvider();
218   void WrapDevicesOnAdbThread(const QueryDevicesCallback& callback,
219                               const AndroidUsbDevices& devices);
220   void EnumeratedDevices(const QueryDevicesCallback& callback,
221                          const AndroidUsbDevices& devices);
222
223   scoped_ptr<crypto::RSAPrivateKey>  rsa_key_;
224 };
225
226 UsbDeviceProvider::UsbDeviceProvider(Profile* profile){
227   rsa_key_.reset(AndroidRSAPrivateKey(profile));
228 }
229
230 UsbDeviceProvider::~UsbDeviceProvider() {
231 }
232
233 void UsbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
234   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
235   AndroidUsbDevice::Enumerate(rsa_key_.get(),
236                               base::Bind(&UsbDeviceProvider::EnumeratedDevices,
237                               this, callback));
238 }
239
240 void UsbDeviceProvider::EnumeratedDevices(const QueryDevicesCallback& callback,
241                                           const AndroidUsbDevices& devices) {
242   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
243   adb_thread_->message_loop()->PostTask(FROM_HERE,
244                           base::Bind(&UsbDeviceProvider::WrapDevicesOnAdbThread,
245                           this, callback, devices));
246 }
247
248 void UsbDeviceProvider::WrapDevicesOnAdbThread(
249     const QueryDevicesCallback& callback,const AndroidUsbDevices& devices) {
250   DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
251   AndroidDevices result;
252   for (AndroidUsbDevices::const_iterator it = devices.begin();
253       it != devices.end(); ++it)
254     result.push_back(new UsbDeviceImpl(*it));
255
256   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
257                           base::Bind(&UsbDeviceProvider::RunCallbackOnUIThread,
258                           callback, result));
259 }
260
261 } // namespace
262
263 // AndroidDevice -------------------------------------------
264
265 AndroidDevice::AndroidDevice(const std::string& serial, bool is_connected)
266     : serial_(serial),
267       is_connected_(is_connected) {
268 }
269
270 void AndroidDevice::HttpQuery(
271     const std::string& la_name,
272     const std::string& request,
273     const CommandCallback& callback) {
274   OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this,
275                                  request, callback));
276 }
277
278 void AndroidDevice::HttpUpgrade(
279     const std::string& la_name,
280     const std::string& request,
281     const SocketCallback& callback) {
282   OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened2, this,
283                                  request, callback));
284 }
285
286 AndroidDevice::~AndroidDevice() {
287 }
288
289 void AndroidDevice::OnHttpSocketOpened(
290     const std::string& request,
291     const CommandCallback& callback,
292     int result,
293     net::StreamSocket* socket) {
294   if (result != net::OK) {
295     callback.Run(result, std::string());
296     return;
297   }
298   AdbClientSocket::HttpQuery(socket, request, callback);
299 }
300
301 void AndroidDevice::OnHttpSocketOpened2(
302     const std::string& request,
303     const SocketCallback& callback,
304     int result,
305     net::StreamSocket* socket) {
306   if (result != net::OK) {
307     callback.Run(result, NULL);
308     return;
309   }
310   AdbClientSocket::HttpQuery(socket, request, callback);
311 }
312
313 // AdbCountDevicesCommand -----------------------------------------------------
314 // TODO(zvorygin): Remove this class.
315 class AdbCountDevicesCommand : public base::RefCountedThreadSafe<
316     AdbCountDevicesCommand, BrowserThread::DeleteOnUIThread> {
317  public:
318   typedef base::Callback<void(int)> Callback;
319
320   AdbCountDevicesCommand(
321       scoped_refptr<RefCountedAdbThread> adb_thread,
322       const Callback& callback);
323
324  private:
325   friend struct BrowserThread::DeleteOnThread<
326       BrowserThread::UI>;
327   friend class base::DeleteHelper<AdbCountDevicesCommand>;
328
329   virtual ~AdbCountDevicesCommand();
330   void RequestAdbDeviceCount();
331   void ReceivedAdbDeviceCount(int result, const std::string& response);
332   void Respond(int count);
333
334   scoped_refptr<RefCountedAdbThread> adb_thread_;
335   Callback callback_;
336 };
337
338 AdbCountDevicesCommand::AdbCountDevicesCommand(
339     scoped_refptr<RefCountedAdbThread> adb_thread,
340     const Callback& callback)
341     : adb_thread_(adb_thread),
342       callback_(callback) {
343   adb_thread_->message_loop()->PostTask(
344       FROM_HERE, base::Bind(&AdbCountDevicesCommand::RequestAdbDeviceCount,
345                             this));
346 }
347
348 AdbCountDevicesCommand::~AdbCountDevicesCommand() {
349   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
350 }
351
352 void AdbCountDevicesCommand::RequestAdbDeviceCount() {
353   DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
354   AdbClientSocket::AdbQuery(
355       kAdbPort, kHostDevicesCommand,
356       base::Bind(&AdbCountDevicesCommand::ReceivedAdbDeviceCount, this));
357 }
358
359 void AdbCountDevicesCommand::ReceivedAdbDeviceCount(
360     int result,
361     const std::string& response) {
362   DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
363   std::vector<std::string> serials;
364   Tokenize(response, "\n", &serials);
365   BrowserThread::PostTask(
366       BrowserThread::UI, FROM_HERE,
367       base::Bind(&AdbCountDevicesCommand::Respond, this, serials.size()));
368 }
369
370 void AdbCountDevicesCommand::Respond(int count) {
371   callback_.Run(count);
372 }
373
374 // AndroidDeviceProvider ---------------------------------------------------
375
376 AndroidDeviceProvider::AndroidDeviceProvider()
377   : adb_thread_(RefCountedAdbThread::GetInstance()) {
378
379 }
380
381 AndroidDeviceProvider::~AndroidDeviceProvider() {
382 }
383
384 // static
385 void AndroidDeviceProvider::RunCallbackOnUIThread(
386     const QueryDevicesCallback& callback,
387     const AndroidDevices& result) {
388   callback.Run(result);
389 }
390
391 // static
392 void AndroidDeviceProvider::CountDevices(bool discover_usb_devices,
393     const base::Callback<void(int)>& callback) {
394   if (discover_usb_devices) {
395     AndroidUsbDevice::CountDevices(callback);
396     return;
397   }
398
399   new AdbCountDevicesCommand(RefCountedAdbThread::GetInstance(), callback);
400 }
401
402 // static
403 scoped_refptr<AndroidDeviceProvider>
404     AndroidDeviceProvider::GetUsbDeviceProvider(Profile* profile) {
405   return new UsbDeviceProvider(profile);
406 }
407
408 // static
409 scoped_refptr<AndroidDeviceProvider>
410     AndroidDeviceProvider::GetAdbDeviceProvider() {
411   return new AdbDeviceProvider();
412 }