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