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/android_device_manager.h" 6 7 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_util.h" 9 #include "base/strings/stringprintf.h" 10 #include "net/base/io_buffer.h" 11 #include "net/base/net_errors.h" 12 #include "net/socket/stream_socket.h" 13 14 using content::BrowserThread; 15 16 namespace { 17 18 const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; 19 20 const int kBufferSize = 16 * 1024; 21 22 static const char kModelOffline[] = "Offline"; 23 24 static const char kHttpGetRequest[] = "GET %s HTTP/1.1\r\n\r\n"; 25 26 static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n" 27 "Upgrade: WebSocket\r\n" 28 "Connection: Upgrade\r\n" 29 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" 30 "Sec-WebSocket-Version: 13\r\n" 31 "\r\n"; 32 33 static void PostDeviceInfoCallback( 34 scoped_refptr<base::MessageLoopProxy> response_message_loop, 35 const AndroidDeviceManager::DeviceInfoCallback& callback, 36 const AndroidDeviceManager::DeviceInfo& device_info) { 37 response_message_loop->PostTask(FROM_HERE, base::Bind(callback, device_info)); 38 } 39 40 static void PostCommandCallback( 41 scoped_refptr<base::MessageLoopProxy> response_message_loop, 42 const AndroidDeviceManager::CommandCallback& callback, 43 int result, 44 const std::string& response) { 45 response_message_loop->PostTask(FROM_HERE, 46 base::Bind(callback, result, response)); 47 } 48 49 static void PostSocketCallback( 50 scoped_refptr<base::MessageLoopProxy> response_message_loop, 51 const AndroidDeviceManager::SocketCallback& callback, 52 int result, 53 net::StreamSocket* socket) { 54 response_message_loop->PostTask(FROM_HERE, 55 base::Bind(callback, result, socket)); 56 } 57 58 class HttpRequest { 59 public: 60 typedef AndroidDeviceManager::CommandCallback CommandCallback; 61 typedef AndroidDeviceManager::SocketCallback SocketCallback; 62 63 static void CommandRequest(const std::string& request, 64 const CommandCallback& callback, 65 int result, 66 net::StreamSocket* socket) { 67 if (result != net::OK) { 68 callback.Run(result, std::string()); 69 return; 70 } 71 new HttpRequest(socket, request, callback); 72 } 73 74 static void SocketRequest(const std::string& request, 75 const SocketCallback& callback, 76 int result, 77 net::StreamSocket* socket) { 78 if (result != net::OK) { 79 callback.Run(result, NULL); 80 return; 81 } 82 new HttpRequest(socket, request, callback); 83 } 84 85 private: 86 HttpRequest(net::StreamSocket* socket, 87 const std::string& request, 88 const CommandCallback& callback) 89 : socket_(socket), command_callback_(callback), body_pos_(0) { 90 SendRequest(request); 91 } 92 93 HttpRequest(net::StreamSocket* socket, 94 const std::string& request, 95 const SocketCallback& callback) 96 : socket_(socket), 97 socket_callback_(callback), 98 body_pos_(0) { 99 SendRequest(request); 100 } 101 102 ~HttpRequest() { 103 } 104 105 void SendRequest(const std::string& request) { 106 scoped_refptr<net::StringIOBuffer> request_buffer = 107 new net::StringIOBuffer(request); 108 109 int result = socket_->Write( 110 request_buffer.get(), 111 request_buffer->size(), 112 base::Bind(&HttpRequest::ReadResponse, base::Unretained(this))); 113 if (result != net::ERR_IO_PENDING) 114 ReadResponse(result); 115 } 116 117 void ReadResponse(int result) { 118 if (!CheckNetResultOrDie(result)) 119 return; 120 scoped_refptr<net::IOBuffer> response_buffer = 121 new net::IOBuffer(kBufferSize); 122 123 result = socket_->Read( 124 response_buffer.get(), 125 kBufferSize, 126 base::Bind(&HttpRequest::OnResponseData, base::Unretained(this), 127 response_buffer, 128 -1)); 129 if (result != net::ERR_IO_PENDING) 130 OnResponseData(response_buffer, -1, result); 131 } 132 133 void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, 134 int bytes_total, 135 int result) { 136 if (!CheckNetResultOrDie(result)) 137 return; 138 if (result == 0) { 139 CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED); 140 return; 141 } 142 143 response_ += std::string(response_buffer->data(), result); 144 int expected_length = 0; 145 if (bytes_total < 0) { 146 // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header. 147 size_t content_pos = response_.find("Content-Length:"); 148 if (content_pos != std::string::npos) { 149 size_t endline_pos = response_.find("\n", content_pos); 150 if (endline_pos != std::string::npos) { 151 std::string len = response_.substr(content_pos + 15, 152 endline_pos - content_pos - 15); 153 base::TrimWhitespace(len, base::TRIM_ALL, &len); 154 if (!base::StringToInt(len, &expected_length)) { 155 CheckNetResultOrDie(net::ERR_FAILED); 156 return; 157 } 158 } 159 } 160 161 body_pos_ = response_.find("\r\n\r\n"); 162 if (body_pos_ != std::string::npos) { 163 body_pos_ += 4; 164 bytes_total = body_pos_ + expected_length; 165 } 166 } 167 168 if (bytes_total == static_cast<int>(response_.length())) { 169 if (!command_callback_.is_null()) 170 command_callback_.Run(net::OK, response_.substr(body_pos_)); 171 else 172 socket_callback_.Run(net::OK, socket_.release()); 173 delete this; 174 return; 175 } 176 177 result = socket_->Read( 178 response_buffer.get(), 179 kBufferSize, 180 base::Bind(&HttpRequest::OnResponseData, 181 base::Unretained(this), 182 response_buffer, 183 bytes_total)); 184 if (result != net::ERR_IO_PENDING) 185 OnResponseData(response_buffer, bytes_total, result); 186 } 187 188 bool CheckNetResultOrDie(int result) { 189 if (result >= 0) 190 return true; 191 if (!command_callback_.is_null()) 192 command_callback_.Run(result, std::string()); 193 else 194 socket_callback_.Run(result, NULL); 195 delete this; 196 return false; 197 } 198 199 scoped_ptr<net::StreamSocket> socket_; 200 std::string response_; 201 AndroidDeviceManager::CommandCallback command_callback_; 202 AndroidDeviceManager::SocketCallback socket_callback_; 203 size_t body_pos_; 204 }; 205 206 class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> { 207 public: 208 typedef AndroidDeviceManager::DeviceInfo DeviceInfo; 209 typedef AndroidDeviceManager::DeviceProvider DeviceProvider; 210 typedef AndroidDeviceManager::DeviceProviders DeviceProviders; 211 typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors; 212 typedef base::Callback<void(DeviceDescriptors*)> 213 DescriptorsCallback; 214 215 static void Start(scoped_refptr<base::MessageLoopProxy> device_message_loop, 216 const DeviceProviders& providers, 217 const DescriptorsCallback& callback) { 218 // Don't keep counted reference on calling thread; 219 DevicesRequest* request = new DevicesRequest(callback); 220 // Avoid destruction while sending requests 221 request->AddRef(); 222 for (DeviceProviders::const_iterator it = providers.begin(); 223 it != providers.end(); ++it) { 224 device_message_loop->PostTask( 225 FROM_HERE, 226 base::Bind( 227 &DeviceProvider::QueryDevices, 228 *it, 229 base::Bind(&DevicesRequest::ProcessSerials, request, *it))); 230 } 231 device_message_loop->ReleaseSoon(FROM_HERE, request); 232 } 233 234 private: 235 explicit DevicesRequest(const DescriptorsCallback& callback) 236 : response_message_loop_(base::MessageLoopProxy::current()), 237 callback_(callback), 238 descriptors_(new DeviceDescriptors()) { 239 } 240 241 friend class base::RefCountedThreadSafe<DevicesRequest>; 242 ~DevicesRequest() { 243 response_message_loop_->PostTask(FROM_HERE, 244 base::Bind(callback_, descriptors_.release())); 245 } 246 247 typedef std::vector<std::string> Serials; 248 249 void ProcessSerials(scoped_refptr<DeviceProvider> provider, 250 const Serials& serials) { 251 for (Serials::const_iterator it = serials.begin(); it != serials.end(); 252 ++it) { 253 descriptors_->resize(descriptors_->size() + 1); 254 descriptors_->back().provider = provider; 255 descriptors_->back().serial = *it; 256 } 257 } 258 259 scoped_refptr<base::MessageLoopProxy> response_message_loop_; 260 DescriptorsCallback callback_; 261 scoped_ptr<DeviceDescriptors> descriptors_; 262 }; 263 264 void ReleaseDeviceAndProvider( 265 AndroidDeviceManager::DeviceProvider* provider, 266 const std::string& serial) { 267 provider->ReleaseDevice(serial); 268 provider->Release(); 269 } 270 271 } // namespace 272 273 AndroidDeviceManager::BrowserInfo::BrowserInfo() 274 : type(kTypeOther) { 275 } 276 277 AndroidDeviceManager::DeviceInfo::DeviceInfo() 278 : model(kModelOffline), connected(false) { 279 } 280 281 AndroidDeviceManager::DeviceInfo::~DeviceInfo() { 282 } 283 284 AndroidDeviceManager::DeviceDescriptor::DeviceDescriptor() { 285 } 286 287 AndroidDeviceManager::DeviceDescriptor::~DeviceDescriptor() { 288 } 289 290 void AndroidDeviceManager::DeviceProvider::SendJsonRequest( 291 const std::string& serial, 292 const std::string& socket_name, 293 const std::string& request, 294 const CommandCallback& callback) { 295 OpenSocket(serial, 296 socket_name, 297 base::Bind(&HttpRequest::CommandRequest, 298 base::StringPrintf(kHttpGetRequest, request.c_str()), 299 callback)); 300 } 301 302 void AndroidDeviceManager::DeviceProvider::HttpUpgrade( 303 const std::string& serial, 304 const std::string& socket_name, 305 const std::string& url, 306 const SocketCallback& callback) { 307 OpenSocket( 308 serial, 309 socket_name, 310 base::Bind(&HttpRequest::SocketRequest, 311 base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()), 312 callback)); 313 } 314 315 void AndroidDeviceManager::DeviceProvider::ReleaseDevice( 316 const std::string& serial) { 317 } 318 319 AndroidDeviceManager::DeviceProvider::DeviceProvider() { 320 } 321 322 AndroidDeviceManager::DeviceProvider::~DeviceProvider() { 323 } 324 325 void AndroidDeviceManager::Device::QueryDeviceInfo( 326 const DeviceInfoCallback& callback) { 327 device_message_loop_->PostTask( 328 FROM_HERE, 329 base::Bind(&DeviceProvider::QueryDeviceInfo, 330 provider_, 331 serial_, 332 base::Bind(&PostDeviceInfoCallback, 333 base::MessageLoopProxy::current(), 334 callback))); 335 } 336 337 void AndroidDeviceManager::Device::OpenSocket(const std::string& socket_name, 338 const SocketCallback& callback) { 339 device_message_loop_->PostTask( 340 FROM_HERE, 341 base::Bind(&DeviceProvider::OpenSocket, 342 provider_, 343 serial_, 344 socket_name, 345 callback)); 346 } 347 348 void AndroidDeviceManager::Device::SendJsonRequest( 349 const std::string& socket_name, 350 const std::string& request, 351 const CommandCallback& callback) { 352 device_message_loop_->PostTask( 353 FROM_HERE, 354 base::Bind(&DeviceProvider::SendJsonRequest, 355 provider_, 356 serial_, 357 socket_name, 358 request, 359 base::Bind(&PostCommandCallback, 360 base::MessageLoopProxy::current(), 361 callback))); 362 } 363 364 void AndroidDeviceManager::Device::HttpUpgrade(const std::string& socket_name, 365 const std::string& url, 366 const SocketCallback& callback) { 367 device_message_loop_->PostTask( 368 FROM_HERE, 369 base::Bind(&DeviceProvider::HttpUpgrade, 370 provider_, 371 serial_, 372 socket_name, 373 url, 374 base::Bind(&PostSocketCallback, 375 base::MessageLoopProxy::current(), 376 callback))); 377 } 378 379 AndroidDeviceManager::Device::Device( 380 scoped_refptr<base::MessageLoopProxy> device_message_loop, 381 scoped_refptr<DeviceProvider> provider, 382 const std::string& serial) 383 : device_message_loop_(device_message_loop), 384 provider_(provider), 385 serial_(serial), 386 weak_factory_(this) { 387 } 388 389 AndroidDeviceManager::Device::~Device() { 390 provider_->AddRef(); 391 DeviceProvider* raw_ptr = provider_.get(); 392 provider_ = NULL; 393 device_message_loop_->PostTask( 394 FROM_HERE, 395 base::Bind(&ReleaseDeviceAndProvider, 396 base::Unretained(raw_ptr), 397 serial_)); 398 } 399 400 AndroidDeviceManager::HandlerThread* 401 AndroidDeviceManager::HandlerThread::instance_ = NULL; 402 403 // static 404 scoped_refptr<AndroidDeviceManager::HandlerThread> 405 AndroidDeviceManager::HandlerThread::GetInstance() { 406 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 407 if (!instance_) 408 new HandlerThread(); 409 return instance_; 410 } 411 412 AndroidDeviceManager::HandlerThread::HandlerThread() { 413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 414 instance_ = this; 415 thread_ = new base::Thread(kDevToolsAdbBridgeThreadName); 416 base::Thread::Options options; 417 options.message_loop_type = base::MessageLoop::TYPE_IO; 418 if (!thread_->StartWithOptions(options)) { 419 delete thread_; 420 thread_ = NULL; 421 } 422 } 423 424 scoped_refptr<base::MessageLoopProxy> 425 AndroidDeviceManager::HandlerThread::message_loop() { 426 return thread_ ? thread_->message_loop_proxy() : NULL; 427 } 428 429 // static 430 void AndroidDeviceManager::HandlerThread::StopThread( 431 base::Thread* thread) { 432 thread->Stop(); 433 } 434 435 AndroidDeviceManager::HandlerThread::~HandlerThread() { 436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 437 instance_ = NULL; 438 if (!thread_) 439 return; 440 // Shut down thread on FILE thread to join into IO. 441 content::BrowserThread::PostTask( 442 content::BrowserThread::FILE, FROM_HERE, 443 base::Bind(&HandlerThread::StopThread, thread_)); 444 } 445 446 // static 447 scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() { 448 return new AndroidDeviceManager(); 449 } 450 451 void AndroidDeviceManager::SetDeviceProviders( 452 const DeviceProviders& providers) { 453 for (DeviceProviders::iterator it = providers_.begin(); 454 it != providers_.end(); ++it) { 455 (*it)->AddRef(); 456 DeviceProvider* raw_ptr = it->get(); 457 *it = NULL; 458 handler_thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr); 459 } 460 providers_ = providers; 461 } 462 463 void AndroidDeviceManager::QueryDevices(const DevicesCallback& callback) { 464 DevicesRequest::Start(handler_thread_->message_loop(), 465 providers_, 466 base::Bind(&AndroidDeviceManager::UpdateDevices, 467 this, 468 callback)); 469 } 470 471 AndroidDeviceManager::AndroidDeviceManager() 472 : handler_thread_(HandlerThread::GetInstance()) { 473 } 474 475 AndroidDeviceManager::~AndroidDeviceManager() { 476 SetDeviceProviders(DeviceProviders()); 477 } 478 479 void AndroidDeviceManager::UpdateDevices( 480 const DevicesCallback& callback, 481 DeviceDescriptors* descriptors_raw) { 482 scoped_ptr<DeviceDescriptors> descriptors(descriptors_raw); 483 Devices response; 484 DeviceWeakMap new_devices; 485 for (DeviceDescriptors::const_iterator it = descriptors->begin(); 486 it != descriptors->end(); 487 ++it) { 488 DeviceWeakMap::iterator found = devices_.find(it->serial); 489 scoped_refptr<Device> device; 490 if (found == devices_.end() || !found->second 491 || found->second->provider_ != it->provider) { 492 device = new Device(handler_thread_->message_loop(), 493 it->provider, it->serial); 494 } else { 495 device = found->second.get(); 496 } 497 response.push_back(device); 498 new_devices[it->serial] = device->weak_factory_.GetWeakPtr(); 499 } 500 devices_.swap(new_devices); 501 callback.Run(response); 502 } 503