Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 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/devtools_device_provider.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 const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; | |
| 18 const char kHostTransportCommand[] = "host:transport:%s|%s"; | |
| 19 const char kHostDevicesCommand[] = "host:devices"; | |
| 20 const char kLocalAbstractCommand[] = "localabstract:%s"; | |
| 21 | |
| 22 const int kAdbPort = 5037; | |
| 23 const int kBufferSize = 16 * 1024; | |
| 24 | |
| 25 // AndroidDevice ------------------------------------------- | |
| 26 | |
| 27 AndroidDevice::AndroidDevice(const std::string& serial) | |
| 28 : serial_(serial) { | |
| 29 } | |
| 30 | |
| 31 void AndroidDevice::HttpQuery( | |
| 32 const std::string& la_name, | |
| 33 const std::string& request, | |
| 34 const CommandCallback& callback) { | |
| 35 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this, | |
| 36 request, callback)); | |
| 37 } | |
| 38 | |
| 39 void AndroidDevice::HttpUpgrade( | |
| 40 const std::string& la_name, | |
| 41 const std::string& request, | |
| 42 const SocketCallback& callback) { | |
| 43 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened2, this, | |
| 44 request, callback)); | |
| 45 } | |
| 46 | |
| 47 AndroidDevice::~AndroidDevice() { | |
| 48 } | |
| 49 | |
| 50 void AndroidDevice::OnHttpSocketOpened( | |
| 51 const std::string& request, | |
| 52 const CommandCallback& callback, | |
| 53 int result, | |
| 54 net::StreamSocket* socket) { | |
| 55 if (result != net::OK) { | |
| 56 callback.Run(result, std::string()); | |
| 57 return; | |
| 58 } | |
| 59 AdbClientSocket::HttpQuery(socket, request, callback); | |
| 60 } | |
| 61 | |
| 62 void AndroidDevice::OnHttpSocketOpened2( | |
| 63 const std::string& request, | |
| 64 const SocketCallback& callback, | |
| 65 int result, | |
| 66 net::StreamSocket* socket) { | |
| 67 if (result != net::OK) { | |
| 68 callback.Run(result, NULL); | |
| 69 return; | |
| 70 } | |
| 71 AdbClientSocket::HttpQuery(socket, request, callback); | |
| 72 } | |
| 73 | |
| 74 // AdbDeviceImpl -------------------------------------------------------------- | |
|
Vladislav Kaznacheev
2013/10/17 20:17:37
Please hide *Impl classes in an anonymous namespac
Dmitry Zvorygin
2013/10/21 07:40:29
Done.
| |
| 75 | |
| 76 class AdbDeviceImpl : public AndroidDevice { | |
| 77 public: | |
| 78 explicit AdbDeviceImpl(const std::string& serial); | |
| 79 virtual void RunCommand(const std::string& command, | |
| 80 const CommandCallback& callback) OVERRIDE; | |
| 81 virtual void OpenSocket(const std::string& name, | |
| 82 const SocketCallback& callback) OVERRIDE; | |
| 83 virtual bool IsConnected() OVERRIDE; | |
| 84 | |
| 85 private: | |
| 86 virtual ~AdbDeviceImpl() {} | |
| 87 }; | |
| 88 | |
| 89 AdbDeviceImpl::AdbDeviceImpl(const std::string& serial) | |
| 90 : AndroidDevice(serial) { | |
| 91 } | |
| 92 | |
| 93 void AdbDeviceImpl::RunCommand(const std::string& command, | |
| 94 const CommandCallback& callback) { | |
| 95 std::string query = base::StringPrintf(kHostTransportCommand, | |
| 96 serial().c_str(), command.c_str()); | |
| 97 AdbClientSocket::AdbQuery(kAdbPort, query, callback); | |
| 98 } | |
| 99 | |
| 100 void AdbDeviceImpl::OpenSocket(const std::string& name, | |
| 101 const SocketCallback& callback) { | |
| 102 std::string socket_name = | |
| 103 base::StringPrintf(kLocalAbstractCommand, name.c_str()); | |
| 104 AdbClientSocket::TransportQuery(kAdbPort, serial(), socket_name, callback); | |
| 105 } | |
| 106 | |
| 107 bool AdbDeviceImpl::IsConnected() { | |
| 108 return true; | |
| 109 } | |
| 110 | |
| 111 // DevToolsDeviceProvider --------------------------------------------------- | |
| 112 | |
| 113 DevToolsDeviceProvider::~DevToolsDeviceProvider() { | |
| 114 } | |
| 115 | |
| 116 void DevToolsDeviceProvider::RunCallbackOnUIThread( | |
|
Vladislav Kaznacheev
2013/10/17 20:17:37
This method could be static.
More over, it could
Dmitry Zvorygin
2013/10/21 07:40:29
This requires callback to be refcounted, so it act
| |
| 117 const QueryDeviceCallback& callback, | |
| 118 const AndroidDevices& result) { | |
| 119 callback.Run(result); | |
| 120 } | |
| 121 | |
| 122 | |
| 123 // UsbDeviceImpl -------------------------------------------------------------- | |
| 124 | |
| 125 class UsbDeviceImpl : public AndroidDevice { | |
| 126 public: | |
| 127 explicit UsbDeviceImpl(AndroidUsbDevice* device); | |
| 128 virtual void RunCommand(const std::string& command, | |
| 129 const CommandCallback& callback) OVERRIDE; | |
| 130 virtual void OpenSocket(const std::string& name, | |
| 131 const SocketCallback& callback) OVERRIDE; | |
| 132 virtual bool IsConnected() OVERRIDE; | |
| 133 | |
| 134 private: | |
| 135 void OnOpenSocket(const SocketCallback& callback, | |
| 136 net::StreamSocket* socket, | |
| 137 int result); | |
| 138 void OpenedForCommand(const CommandCallback& callback, | |
| 139 net::StreamSocket* socket, | |
| 140 int result); | |
| 141 void OnRead(net::StreamSocket* socket, | |
| 142 scoped_refptr<net::IOBuffer> buffer, | |
| 143 const std::string& data, | |
| 144 const CommandCallback& callback, | |
| 145 int result); | |
| 146 | |
| 147 virtual ~UsbDeviceImpl() {} | |
| 148 scoped_refptr<AndroidUsbDevice> device_; | |
| 149 }; | |
| 150 | |
| 151 | |
| 152 UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device) | |
| 153 : AndroidDevice(device->serial()), | |
| 154 device_(device) { | |
| 155 device_->InitOnCallerThread(); | |
| 156 } | |
| 157 | |
| 158 void UsbDeviceImpl::RunCommand(const std::string& command, | |
| 159 const CommandCallback& callback) { | |
| 160 net::StreamSocket* socket = device_->CreateSocket(command); | |
| 161 int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand, | |
| 162 this, callback, socket)); | |
| 163 if (result != net::ERR_IO_PENDING) | |
| 164 callback.Run(result, std::string()); | |
| 165 } | |
| 166 | |
| 167 void UsbDeviceImpl::OpenSocket(const std::string& name, | |
| 168 const SocketCallback& callback) { | |
| 169 std::string socket_name = | |
| 170 base::StringPrintf(kLocalAbstractCommand, name.c_str()); | |
| 171 net::StreamSocket* socket = device_->CreateSocket(socket_name); | |
| 172 int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this, | |
| 173 callback, socket)); | |
| 174 if (result != net::ERR_IO_PENDING) | |
| 175 callback.Run(result, NULL); | |
| 176 } | |
| 177 | |
| 178 void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback, | |
| 179 net::StreamSocket* socket, | |
| 180 int result) { | |
| 181 callback.Run(result, result == net::OK ? socket : NULL); | |
| 182 } | |
| 183 | |
| 184 void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback, | |
| 185 net::StreamSocket* socket, | |
| 186 int result) { | |
| 187 if (result != net::OK) { | |
| 188 callback.Run(result, std::string()); | |
| 189 return; | |
| 190 } | |
| 191 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize); | |
| 192 result = socket->Read(buffer, kBufferSize, | |
| 193 base::Bind(&UsbDeviceImpl::OnRead, this, | |
| 194 socket, buffer, std::string(), callback)); | |
| 195 if (result != net::ERR_IO_PENDING) | |
| 196 OnRead(socket, buffer, std::string(), callback, result); | |
| 197 } | |
| 198 | |
| 199 void UsbDeviceImpl::OnRead(net::StreamSocket* socket, | |
| 200 scoped_refptr<net::IOBuffer> buffer, | |
| 201 const std::string& data, | |
| 202 const CommandCallback& callback, | |
| 203 int result) { | |
| 204 if (result <= 0) { | |
| 205 callback.Run(result, result == 0 ? data : std::string()); | |
| 206 delete socket; | |
| 207 return; | |
| 208 } | |
| 209 | |
| 210 std::string new_data = data + std::string(buffer->data(), result); | |
| 211 result = socket->Read(buffer, kBufferSize, | |
| 212 base::Bind(&UsbDeviceImpl::OnRead, this, | |
| 213 socket, buffer, new_data, callback)); | |
| 214 if (result != net::ERR_IO_PENDING) | |
| 215 OnRead(socket, buffer, new_data, callback, result); | |
| 216 } | |
| 217 | |
| 218 bool UsbDeviceImpl::IsConnected() { | |
| 219 return device_->is_connected(); | |
| 220 } | |
| 221 | |
| 222 // UsbDeviceProvider ------------------------------------------- | |
| 223 | |
| 224 UsbDeviceProvider::UsbDeviceProvider(Profile* profile, | |
| 225 scoped_refptr<RefCountedAdbThread> adb_thread) : adb_thread_(adb_thread) { | |
| 226 rsa_key_.reset(AndroidRSAPrivateKey(profile)); | |
| 227 } | |
| 228 | |
| 229 UsbDeviceProvider::~UsbDeviceProvider() { | |
| 230 } | |
| 231 | |
| 232 void UsbDeviceProvider::QueryDevices(const QueryDeviceCallback& callback) { | |
| 233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 234 AndroidUsbDevice::Enumerate(rsa_key_.get(), | |
| 235 base::Bind(&UsbDeviceProvider::EnumeratedDevices, | |
| 236 this, callback)); | |
| 237 } | |
| 238 | |
| 239 void UsbDeviceProvider::EnumeratedDevices(const QueryDeviceCallback& callback, | |
| 240 const AndroidUsbDevices& devices) { | |
| 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 242 adb_thread_->message_loop()->PostTask(FROM_HERE, | |
| 243 base::Bind(&UsbDeviceProvider::WrapDevicesOnAdbThread, | |
| 244 this, callback, devices)); | |
| 245 } | |
| 246 | |
| 247 void UsbDeviceProvider::WrapDevicesOnAdbThread( | |
| 248 const QueryDeviceCallback& callback,const AndroidUsbDevices& devices) { | |
| 249 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); | |
| 250 AndroidDevices result; | |
| 251 for (AndroidUsbDevices::const_iterator it = devices.begin(); | |
| 252 it != devices.end(); ++it) | |
| 253 result.push_back(new UsbDeviceImpl(*it)); | |
| 254 | |
| 255 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 256 base::Bind(&UsbDeviceProvider::RunCallbackOnUIThread, | |
| 257 this, callback, result)); | |
| 258 } | |
| 259 | |
| 260 // AdbDeviceProvider ------------------------------------------- | |
| 261 | |
| 262 AdbDeviceProvider::AdbDeviceProvider( | |
| 263 scoped_refptr<RefCountedAdbThread> adb_thread) : adb_thread_(adb_thread) { | |
| 264 } | |
| 265 | |
| 266 AdbDeviceProvider::~AdbDeviceProvider() { | |
| 267 } | |
| 268 | |
| 269 void AdbDeviceProvider::QueryDevices(const QueryDeviceCallback& callback) { | |
| 270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 271 | |
| 272 adb_thread_->message_loop()->PostTask( | |
| 273 FROM_HERE, base::Bind(&AdbDeviceProvider::QueryDevicesOnAdbThread, | |
| 274 this, callback)); | |
| 275 } | |
| 276 | |
| 277 void AdbDeviceProvider::QueryDevicesOnAdbThread( | |
| 278 const QueryDeviceCallback& callback) { | |
| 279 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); | |
| 280 | |
| 281 AdbClientSocket::AdbQuery( | |
| 282 kAdbPort, kHostDevicesCommand, | |
| 283 base::Bind(&AdbDeviceProvider::ReceivedAdbDevices, this, callback)); | |
| 284 } | |
| 285 | |
| 286 | |
| 287 void AdbDeviceProvider::ReceivedAdbDevices(const QueryDeviceCallback& callback, | |
| 288 int result_code, | |
| 289 const std::string& response) { | |
| 290 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); | |
| 291 | |
| 292 AndroidDevices result; | |
| 293 | |
| 294 #if defined(DEBUG_DEVTOOLS) | |
|
Vladislav Kaznacheev
2013/10/17 20:17:37
Strange ident here and inside the #if
Dmitry Zvorygin
2013/10/21 07:40:29
Done.
| |
| 295 // For desktop remote debugging. | |
| 296 result.push_back(new AdbDeviceImpl("")); | |
| 297 #endif // defined(DEBUG_DEVTOOLS) | |
| 298 | |
| 299 | |
| 300 std::vector<std::string> serials; | |
| 301 Tokenize(response, "\n", &serials); | |
| 302 for (size_t i = 0; i < serials.size(); ++i) { | |
| 303 std::vector<std::string> tokens; | |
| 304 Tokenize(serials[i], "\t ", &tokens); | |
| 305 result.push_back(new AdbDeviceImpl(tokens[0])); | |
| 306 } | |
| 307 | |
| 308 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 309 base::Bind(&AdbDeviceProvider::RunCallbackOnUIThread, | |
| 310 this, callback, result)); | |
| 311 } | |
| OLD | NEW |