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