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 } 413