10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file. 41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/devtools/device/android_device_manager.h" 61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/string_util.h" 91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/stringprintf.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/base/io_buffer.h" 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/base/net_errors.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/socket/stream_socket.h" 131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using content::BrowserThread; 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace { 171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int kBufferSize = 16 * 1024; 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)static const char kModelOffline[] = "Offline"; 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static const char kHttpGetRequest[] = "GET %s HTTP/1.1\r\n\r\n"; 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n" 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "Upgrade: WebSocket\r\n" 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "Connection: Upgrade\r\n" 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "Sec-WebSocket-Version: 13\r\n" 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "\r\n"; 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)static void PostDeviceInfoCallback( 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> response_message_loop, 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AndroidDeviceManager::DeviceInfoCallback& callback, 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AndroidDeviceManager::DeviceInfo& device_info) { 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) response_message_loop->PostTask(FROM_HERE, base::Bind(callback, device_info)); 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)static void PostCommandCallback( 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> response_message_loop, 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AndroidDeviceManager::CommandCallback& callback, 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int result, 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& response) { 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) response_message_loop->PostTask(FROM_HERE, 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(callback, result, response)); 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)static void PostSocketCallback( 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> response_message_loop, 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AndroidDeviceManager::SocketCallback& callback, 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int result, 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<net::StreamSocket> socket) { 546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) response_message_loop->PostTask( 556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FROM_HERE, base::Bind(callback, result, base::Passed(&socket))); 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class HttpRequest { 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) typedef AndroidDeviceManager::CommandCallback CommandCallback; 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) typedef AndroidDeviceManager::SocketCallback SocketCallback; 621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static void CommandRequest(const std::string& request, 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const CommandCallback& callback, 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int result, 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<net::StreamSocket> socket) { 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result != net::OK) { 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(result, std::string()); 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) new HttpRequest(socket.Pass(), request, callback); 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static void SocketRequest(const std::string& request, 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const SocketCallback& callback, 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int result, 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<net::StreamSocket> socket) { 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result != net::OK) { 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) callback.Run(result, make_scoped_ptr<net::StreamSocket>(NULL)); 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) new HttpRequest(socket.Pass(), request, callback); 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private: 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) HttpRequest(scoped_ptr<net::StreamSocket> socket, 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& request, 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const CommandCallback& callback) 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : socket_(socket.Pass()), 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) command_callback_(callback), 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) body_pos_(0) { 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendRequest(request); 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) HttpRequest(scoped_ptr<net::StreamSocket> socket, 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const std::string& request, 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const SocketCallback& callback) 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : socket_(socket.Pass()), 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) socket_callback_(callback), 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) body_pos_(0) { 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendRequest(request); 102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ~HttpRequest() { 105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void SendRequest(const std::string& request) { 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<net::StringIOBuffer> request_buffer = 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new net::StringIOBuffer(request); 1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int result = socket_->Write( 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request_buffer.get(), 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request_buffer->size(), 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HttpRequest::ReadResponse, base::Unretained(this))); 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ReadResponse(result); 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void ReadResponse(int result) { 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<net::IOBuffer> response_buffer = 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new net::IOBuffer(kBufferSize); 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result = socket_->Read( 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) response_buffer.get(), 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kBufferSize, 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HttpRequest::OnResponseData, base::Unretained(this), 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) response_buffer, 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) -1)); 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) OnResponseData(response_buffer, -1, result); 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int bytes_total, 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int result) { 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result == 0) { 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED); 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) response_ += std::string(response_buffer->data(), result); 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int expected_length = 0; 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (bytes_total < 0) { 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header. 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t content_pos = response_.find("Content-Length:"); 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (content_pos != std::string::npos) { 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t endline_pos = response_.find("\n", content_pos); 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (endline_pos != std::string::npos) { 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string len = response_.substr(content_pos + 15, 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) endline_pos - content_pos - 15); 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::TrimWhitespace(len, base::TRIM_ALL, &len); 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!base::StringToInt(len, &expected_length)) { 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CheckNetResultOrDie(net::ERR_FAILED); 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) body_pos_ = response_.find("\r\n\r\n"); 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (body_pos_ != std::string::npos) { 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) body_pos_ += 4; 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bytes_total = body_pos_ + expected_length; 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (bytes_total == static_cast<int>(response_.length())) { 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!command_callback_.is_null()) 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) command_callback_.Run(net::OK, response_.substr(body_pos_)); 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) socket_callback_.Run(net::OK, socket_.Pass()); 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delete this; 176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result = socket_->Read( 180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) response_buffer.get(), 181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kBufferSize, 182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&HttpRequest::OnResponseData, 183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(this), 184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) response_buffer, 185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bytes_total)); 186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) OnResponseData(response_buffer, bytes_total, result); 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool CheckNetResultOrDie(int result) { 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result >= 0) 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!command_callback_.is_null()) 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) command_callback_.Run(result, std::string()); 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else 1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) socket_callback_.Run(result, make_scoped_ptr<net::StreamSocket>(NULL)); 197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delete this; 198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<net::StreamSocket> socket_; 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string response_; 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AndroidDeviceManager::CommandCallback command_callback_; 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AndroidDeviceManager::SocketCallback socket_callback_; 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t body_pos_; 2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}; 2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> { 20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) typedef AndroidDeviceManager::DeviceInfo DeviceInfo; 21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) typedef AndroidDeviceManager::DeviceProvider DeviceProvider; 21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) typedef AndroidDeviceManager::DeviceProviders DeviceProviders; 21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors; 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) typedef base::Callback<void(DeviceDescriptors*)> 21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DescriptorsCallback; 21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static void Start(scoped_refptr<base::MessageLoopProxy> device_message_loop, 21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DeviceProviders& providers, 21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DescriptorsCallback& callback) { 22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Don't keep counted reference on calling thread; 22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DevicesRequest* request = new DevicesRequest(callback); 22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Avoid destruction while sending requests 22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request->AddRef(); 22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (DeviceProviders::const_iterator it = providers.begin(); 22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it != providers.end(); ++it) { 22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_message_loop->PostTask( 22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind( 22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &DeviceProvider::QueryDevices, 23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *it, 23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&DevicesRequest::ProcessSerials, request, *it))); 23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_message_loop->ReleaseSoon(FROM_HERE, request); 23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) explicit DevicesRequest(const DescriptorsCallback& callback) 23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : response_message_loop_(base::MessageLoopProxy::current()), 23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback_(callback), 24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) descriptors_(new DeviceDescriptors()) { 24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) friend class base::RefCountedThreadSafe<DevicesRequest>; 24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ~DevicesRequest() { 24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) response_message_loop_->PostTask(FROM_HERE, 24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(callback_, descriptors_.release())); 24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) typedef std::vector<std::string> Serials; 25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void ProcessSerials(scoped_refptr<DeviceProvider> provider, 25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const Serials& serials) { 25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (Serials::const_iterator it = serials.begin(); it != serials.end(); 25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++it) { 25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) descriptors_->resize(descriptors_->size() + 1); 25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) descriptors_->back().provider = provider; 25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) descriptors_->back().serial = *it; 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> response_message_loop_; 26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DescriptorsCallback callback_; 26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<DeviceDescriptors> descriptors_; 26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ReleaseDeviceAndProvider( 26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AndroidDeviceManager::DeviceProvider* provider, 26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& serial) { 26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider->ReleaseDevice(serial); 27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider->Release(); 27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} // namespace 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AndroidDeviceManager::BrowserInfo::BrowserInfo() 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : type(kTypeOther) { 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::DeviceInfo::DeviceInfo() 28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : model(kModelOffline), connected(false) { 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AndroidDeviceManager::DeviceInfo::~DeviceInfo() { 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::DeviceDescriptor::DeviceDescriptor() { 2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::DeviceDescriptor::~DeviceDescriptor() { 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::DeviceProvider::SendJsonRequest( 29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& serial, 29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& socket_name, 29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& request, 29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const CommandCallback& callback) { 29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OpenSocket(serial, 29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) socket_name, 29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&HttpRequest::CommandRequest, 30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::StringPrintf(kHttpGetRequest, request.c_str()), 30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback)); 30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::DeviceProvider::HttpUpgrade( 30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& serial, 30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& socket_name, 30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& url, 30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const SocketCallback& callback) { 30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OpenSocket( 31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) serial, 31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) socket_name, 31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&HttpRequest::SocketRequest, 31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()), 31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback)); 31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::DeviceProvider::ReleaseDevice( 31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& serial) { 3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 321c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochAndroidDeviceManager::DeviceProvider::DeviceProvider() { 3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 324c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochAndroidDeviceManager::DeviceProvider::~DeviceProvider() { 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::Device::QueryDeviceInfo( 32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DeviceInfoCallback& callback) { 32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_message_loop_->PostTask( 33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&DeviceProvider::QueryDeviceInfo, 33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_, 33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) serial_, 33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&PostDeviceInfoCallback, 33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoopProxy::current(), 33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback))); 337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 338c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::Device::OpenSocket(const std::string& socket_name, 34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const SocketCallback& callback) { 34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_message_loop_->PostTask( 34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&DeviceProvider::OpenSocket, 34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_, 34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) serial_, 34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) socket_name, 34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback)); 348c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::Device::SendJsonRequest( 35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& socket_name, 35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& request, 35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const CommandCallback& callback) { 35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_message_loop_->PostTask( 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&DeviceProvider::SendJsonRequest, 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_, 35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) serial_, 35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) socket_name, 36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request, 36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&PostCommandCallback, 36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoopProxy::current(), 36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback))); 364c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 365c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::Device::HttpUpgrade(const std::string& socket_name, 36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& url, 36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const SocketCallback& callback) { 36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_message_loop_->PostTask( 37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&DeviceProvider::HttpUpgrade, 37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_, 37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) serial_, 37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) socket_name, 37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) url, 37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&PostSocketCallback, 37746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoopProxy::current(), 37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback))); 379c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 380c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::Device::Device( 38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> device_message_loop, 38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<DeviceProvider> provider, 38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& serial) 38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : device_message_loop_(device_message_loop), 38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_(provider), 38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) serial_(serial), 38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) weak_factory_(this) { 389c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 390c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::Device::~Device() { 39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_->AddRef(); 39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DeviceProvider* raw_ptr = provider_.get(); 39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_ = NULL; 39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device_message_loop_->PostTask( 39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&ReleaseDeviceAndProvider, 39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(raw_ptr), 39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) serial_)); 400c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 401c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::HandlerThread* 40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::HandlerThread::instance_ = NULL; 40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_refptr<AndroidDeviceManager::HandlerThread> 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::HandlerThread::GetInstance() { 40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!instance_) 41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new HandlerThread(); 41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return instance_; 412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 413c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::HandlerThread::HandlerThread() { 41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) instance_ = this; 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) thread_ = new base::Thread(kDevToolsAdbBridgeThreadName); 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Thread::Options options; 41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_IO; 42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!thread_->StartWithOptions(options)) { 42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) delete thread_; 42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) thread_ = NULL; 423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 424c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 425c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_refptr<base::MessageLoopProxy> 42746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::HandlerThread::message_loop() { 42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return thread_ ? thread_->message_loop_proxy() : NULL; 429c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 430c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static 43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::HandlerThread::StopThread( 43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Thread* thread) { 43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) thread->Stop(); 435c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 436c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::HandlerThread::~HandlerThread() { 43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) instance_ = NULL; 44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!thread_) 441c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Shut down thread on FILE thread to join into IO. 44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) content::BrowserThread::PostTask( 44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) content::BrowserThread::FILE, FROM_HERE, 44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&HandlerThread::StopThread, thread_)); 44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 447c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static 44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() { 45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return new AndroidDeviceManager(); 45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::SetDeviceProviders( 45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DeviceProviders& providers) { 45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (DeviceProviders::iterator it = providers_.begin(); 45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it != providers_.end(); ++it) { 45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (*it)->AddRef(); 45846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DeviceProvider* raw_ptr = it->get(); 45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *it = NULL; 46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) handler_thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr); 461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) providers_ = providers; 46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::QueryDevices(const DevicesCallback& callback) { 46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DevicesRequest::Start(handler_thread_->message_loop(), 46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) providers_, 46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&AndroidDeviceManager::UpdateDevices, 46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, 47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback)); 47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::AndroidDeviceManager() 47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : handler_thread_(HandlerThread::GetInstance()) { 47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 476c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 47746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)AndroidDeviceManager::~AndroidDeviceManager() { 47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SetDeviceProviders(DeviceProviders()); 479c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 480c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void AndroidDeviceManager::UpdateDevices( 48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DevicesCallback& callback, 48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DeviceDescriptors* descriptors_raw) { 48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<DeviceDescriptors> descriptors(descriptors_raw); 48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Devices response; 48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DeviceWeakMap new_devices; 48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (DeviceDescriptors::const_iterator it = descriptors->begin(); 48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it != descriptors->end(); 48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++it) { 49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DeviceWeakMap::iterator found = devices_.find(it->serial); 49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<Device> device; 4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (found == devices_.end() || !found->second || 4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci found->second->provider_.get() != it->provider.get()) { 49446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device = new Device(handler_thread_->message_loop(), 49546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) it->provider, it->serial); 49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) device = found->second.get(); 49846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) response.push_back(device); 50046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new_devices[it->serial] = device->weak_factory_.GetWeakPtr(); 50146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 50246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) devices_.swap(new_devices); 50346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.Run(response); 504c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 505