Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / devtools / device / usb / usb_device_provider.cc
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.
4
5 #include "chrome/browser/devtools/device/usb/usb_device_provider.h"
6
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"
13
14 namespace {
15
16 const char kLocalAbstractCommand[] = "localabstract:%s";
17
18 const int kBufferSize = 16 * 1024;
19
20 class UsbDeviceImpl : public AndroidDeviceManager::Device {
21  public:
22   explicit UsbDeviceImpl(AndroidUsbDevice* device);
23
24   virtual void RunCommand(const std::string& command,
25                           const CommandCallback& callback) OVERRIDE;
26
27   virtual void OpenSocket(const std::string& name,
28                           const SocketCallback& callback) OVERRIDE;
29  private:
30   void OnOpenSocket(const SocketCallback& callback,
31                     net::StreamSocket* socket,
32                     int result);
33   void OpenedForCommand(const CommandCallback& callback,
34                         net::StreamSocket* socket,
35                         int result);
36   void OnRead(net::StreamSocket* socket,
37               scoped_refptr<net::IOBuffer> buffer,
38               const std::string& data,
39               const CommandCallback& callback,
40               int result);
41
42   virtual ~UsbDeviceImpl() {}
43   scoped_refptr<AndroidUsbDevice> device_;
44 };
45
46
47 UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device)
48     : Device(device->serial(), device->is_connected()),
49       device_(device) {
50   device_->InitOnCallerThread();
51 }
52
53 void UsbDeviceImpl::RunCommand(const std::string& command,
54                                const CommandCallback& callback) {
55   DCHECK(CalledOnValidThread());
56   net::StreamSocket* socket = device_->CreateSocket(command);
57   if (!socket) {
58     callback.Run(net::ERR_CONNECTION_FAILED, std::string());
59     return;
60   }
61   int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand,
62                                           this, callback, socket));
63   if (result != net::ERR_IO_PENDING)
64     callback.Run(result, std::string());
65 }
66
67 void UsbDeviceImpl::OpenSocket(const std::string& name,
68                                const SocketCallback& callback) {
69   DCHECK(CalledOnValidThread());
70   std::string socket_name =
71       base::StringPrintf(kLocalAbstractCommand, name.c_str());
72   net::StreamSocket* socket = device_->CreateSocket(socket_name);
73   if (!socket) {
74     callback.Run(net::ERR_CONNECTION_FAILED, NULL);
75     return;
76   }
77   int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this,
78                                           callback, socket));
79   if (result != net::ERR_IO_PENDING)
80     callback.Run(result, NULL);
81 }
82
83 void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback,
84                   net::StreamSocket* socket,
85                   int result) {
86   callback.Run(result, result == net::OK ? socket : NULL);
87 }
88
89 void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback,
90                                      net::StreamSocket* socket,
91                                      int result) {
92   if (result != net::OK) {
93     callback.Run(result, std::string());
94     return;
95   }
96   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
97   result = socket->Read(buffer, kBufferSize,
98                         base::Bind(&UsbDeviceImpl::OnRead, this,
99                                    socket, buffer, std::string(), callback));
100   if (result != net::ERR_IO_PENDING)
101     OnRead(socket, buffer, std::string(), callback, result);
102 }
103
104 void UsbDeviceImpl::OnRead(net::StreamSocket* socket,
105                            scoped_refptr<net::IOBuffer> buffer,
106                            const std::string& data,
107                            const CommandCallback& callback,
108                            int result) {
109   if (result <= 0) {
110     callback.Run(result, result == 0 ? data : std::string());
111     delete socket;
112     return;
113   }
114
115   std::string new_data = data + std::string(buffer->data(), result);
116   result = socket->Read(buffer, kBufferSize,
117                         base::Bind(&UsbDeviceImpl::OnRead, this,
118                                    socket, buffer, new_data, callback));
119   if (result != net::ERR_IO_PENDING)
120     OnRead(socket, buffer, new_data, callback, result);
121 }
122
123 static void EnumeratedDevices(
124     const UsbDeviceProvider::QueryDevicesCallback& callback,
125     const AndroidUsbDevices& devices) {
126   AndroidDeviceManager::Devices result;
127   for (AndroidUsbDevices::const_iterator it = devices.begin();
128       it != devices.end(); ++it)
129     result.push_back(new UsbDeviceImpl(*it));
130   callback.Run(result);
131 }
132
133 } // namespace
134
135 // static
136 void UsbDeviceProvider::CountDevices(
137     const base::Callback<void(int)>& callback) {
138   AndroidUsbDevice::CountDevices(callback);
139 }
140
141 UsbDeviceProvider::UsbDeviceProvider(Profile* profile){
142   rsa_key_.reset(AndroidRSAPrivateKey(profile));
143 }
144
145 UsbDeviceProvider::~UsbDeviceProvider() {
146 }
147
148 void UsbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
149   AndroidUsbDevice::Enumerate(
150       rsa_key_.get(), base::Bind(&EnumeratedDevices, callback));
151 }