10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/devtools/device/adb/adb_client_socket.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/net_util.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/tcp_client_socket.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kBufferSize = 16 * 1024; 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kOkayResponse[] = "OKAY"; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kHostTransportCommand[] = "host:transport:%s"; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kLocalhost[] = "127.0.0.1"; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef base::Callback<void(int, const std::string&)> CommandCallback; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)typedef base::Callback<void(int, net::StreamSocket*)> SocketCallback; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string EncodeMessage(const std::string& message) { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char kHexChars[] = "0123456789ABCDEF"; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t length = message.length(); 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string result(4, '\0'); 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char b = reinterpret_cast<const char*>(&length)[1]; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result[0] = kHexChars[(b >> 4) & 0xf]; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result[1] = kHexChars[b & 0xf]; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) b = reinterpret_cast<const char*>(&length)[0]; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result[2] = kHexChars[(b >> 4) & 0xf]; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result[3] = kHexChars[b & 0xf]; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result + message; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AdbTransportSocket : public AdbClientSocket { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AdbTransportSocket(int port, 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& serial, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& socket_name, 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SocketCallback& callback) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : AdbClientSocket(port), 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) serial_(serial), 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) socket_name_(socket_name), 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_(callback) { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Connect(base::Bind(&AdbTransportSocket::OnConnected, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~AdbTransportSocket() {} 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnConnected(int result) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendCommand(base::StringPrintf(kHostTransportCommand, serial_.c_str()), 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, base::Bind(&AdbTransportSocket::SendLocalAbstract, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SendLocalAbstract(int result, const std::string& response) { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SendCommand(socket_name_, true, 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&AdbTransportSocket::OnSocketAvailable, 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Unretained(this))); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnSocketAvailable(int result, const std::string& response) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.Run(net::OK, socket_.release()); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool CheckNetResultOrDie(int result) { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result >= 0) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.Run(result, NULL); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string serial_; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string socket_name_; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SocketCallback callback_; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AdbQuerySocket : AdbClientSocket { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AdbQuerySocket(int port, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& query, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandCallback& callback) 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : AdbClientSocket(port), 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_query_(0), 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_(callback) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Tokenize(query, "|", &queries_) == 0) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckNetResultOrDie(net::ERR_INVALID_ARGUMENT); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Connect(base::Bind(&AdbQuerySocket::SendNextQuery, 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~AdbQuerySocket() { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SendNextQuery(int result) { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string query = queries_[current_query_]; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (query.length() > 0xFFFF) { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckNetResultOrDie(net::ERR_MSG_TOO_BIG); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_void = current_query_ < queries_.size() - 1; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendCommand(query, is_void, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&AdbQuerySocket::OnResponse, base::Unretained(this))); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnResponse(int result, const std::string& response) { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (++current_query_ < queries_.size()) { 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendNextQuery(net::OK); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.Run(result, response); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool CheckNetResultOrDie(int result) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result >= 0) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_.Run(result, std::string()); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> queries_; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t current_query_; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandCallback callback_; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AdbClientSocket::AdbQuery(int port, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& query, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandCallback& callback) { 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new AdbQuerySocket(port, query, callback); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AdbClientSocket::TransportQuery(int port, 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& serial, 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& socket_name, 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SocketCallback& callback) { 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new AdbTransportSocket(port, serial, socket_name, callback); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AdbClientSocket::AdbClientSocket(int port) 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : host_(kLocalhost), port_(port) { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AdbClientSocket::~AdbClientSocket() { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AdbClientSocket::Connect(const net::CompletionCallback& callback) { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::IPAddressNumber ip_number; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!net::ParseIPLiteralToNumber(host_, &ip_number)) { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(net::ERR_FAILED); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::AddressList address_list = 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::AddressList::CreateFromIPAddress(ip_number, port_); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) socket_.reset(new net::TCPClientSocket(address_list, NULL, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog::Source())); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int result = socket_->Connect(callback); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(result); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AdbClientSocket::SendCommand(const std::string& command, 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_void, 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandCallback& callback) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::StringIOBuffer> request_buffer = 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new net::StringIOBuffer(EncodeMessage(command)); 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = socket_->Write(request_buffer.get(), 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_buffer->size(), 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&AdbClientSocket::ReadResponse, 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback, 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) is_void)); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadResponse(callback, is_void, result); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AdbClientSocket::ReadResponse(const CommandCallback& callback, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_void, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int result) { 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result < 0) { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(result, "IO error"); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> response_buffer = 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new net::IOBuffer(kBufferSize); 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = socket_->Read(response_buffer.get(), 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kBufferSize, 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&AdbClientSocket::OnResponseHeader, 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback, 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) is_void, 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) response_buffer)); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnResponseHeader(callback, is_void, response_buffer, result); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AdbClientSocket::OnResponseHeader( 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandCallback& callback, 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_void, 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> response_buffer, 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int result) { 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result <= 0) { 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(result == 0 ? net::ERR_CONNECTION_CLOSED : result, 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "IO error"); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string data = std::string(response_buffer->data(), result); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result < 4) { 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(net::ERR_FAILED, "Response is too short: " + data); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string status = data.substr(0, 4); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status != kOkayResponse) { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(net::ERR_FAILED, data); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data = data.substr(4); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_void) { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int payload_length = 0; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bytes_left = -1; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data.length() >= 4 && 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::HexStringToInt(data.substr(0, 4), &payload_length)) { 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data = data.substr(4); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_left = payload_length - result + 8; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_left = -1; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnResponseData(callback, data, response_buffer, bytes_left, 0); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(net::OK, data); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AdbClientSocket::OnResponseData( 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CommandCallback& callback, 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& response, 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::IOBuffer> response_buffer, 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bytes_left, 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int result) { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result < 0) { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(result, "IO error"); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_left -= result; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string new_response = 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) response + std::string(response_buffer->data(), result); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bytes_left == 0) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(net::OK, new_response); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Read tail 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = socket_->Read(response_buffer.get(), 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kBufferSize, 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&AdbClientSocket::OnResponseData, 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback, 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_response, 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) response_buffer, 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bytes_left)); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result > 0) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnResponseData(callback, new_response, response_buffer, bytes_left, result); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (result != net::ERR_IO_PENDING) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(net::OK, new_response); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 297