190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/test/chromedriver/net/adb_client_socket.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/compiler_specific.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (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" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/address_list.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/completion_callback.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/net_errors.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/net_util.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/socket/tcp_client_socket.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kBufferSize = 16 * 1024; 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kOkayResponse[] = "OKAY"; 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kHostTransportCommand[] = "host:transport:%s"; 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kLocalAbstractCommand[] = "localabstract:%s"; 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kLocalhost[] = "127.0.0.1"; 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)typedef base::Callback<void(int, const std::string&)> CommandCallback; 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)typedef base::Callback<void(int, net::StreamSocket*)> SocketCallback; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string EncodeMessage(const std::string& message) { 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static const char kHexChars[] = "0123456789ABCDEF"; 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t length = message.length(); 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string result(4, '\0'); 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) char b = reinterpret_cast<const char*>(&length)[1]; 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) result[0] = kHexChars[(b >> 4) & 0xf]; 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) result[1] = kHexChars[b & 0xf]; 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) b = reinterpret_cast<const char*>(&length)[0]; 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) result[2] = kHexChars[(b >> 4) & 0xf]; 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) result[3] = kHexChars[b & 0xf]; 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return result + message; 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class AdbTransportSocket : public AdbClientSocket { 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AdbTransportSocket(int port, 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& serial, 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& socket_name, 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SocketCallback& callback) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : AdbClientSocket(port), 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) serial_(serial), 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) socket_name_(socket_name), 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_(callback) { 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Connect(base::Bind(&AdbTransportSocket::OnConnected, 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(this))); 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ~AdbTransportSocket() {} 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OnConnected(int result) { 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SendCommand(base::StringPrintf(kHostTransportCommand, serial_.c_str()), 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) true, base::Bind(&AdbTransportSocket::SendLocalAbstract, 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(this))); 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SendLocalAbstract(int result, const std::string& response) { 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SendCommand(base::StringPrintf(kLocalAbstractCommand, socket_name_.c_str()), 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) true, base::Bind(&AdbTransportSocket::OnSocketAvailable, 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(this))); 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OnSocketAvailable(int result, const std::string& response) { 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_.Run(net::OK, socket_.release()); 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete this; 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool CheckNetResultOrDie(int result) { 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result >= 0) 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_.Run(result, NULL); 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete this; 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string serial_; 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string socket_name_; 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SocketCallback callback_; 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class HttpOverAdbSocket { 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HttpOverAdbSocket(int port, 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& serial, 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& socket_name, 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& request, 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CommandCallback& callback) 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : request_(request), 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) command_callback_(callback), 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) body_pos_(0) { 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Connect(port, serial, socket_name); 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HttpOverAdbSocket(int port, 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& serial, 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& socket_name, 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& request, 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SocketCallback& callback) 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : request_(request), 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) socket_callback_(callback), 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) body_pos_(0) { 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Connect(port, serial, socket_name); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ~HttpOverAdbSocket() { 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void Connect(int port, 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& serial, 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& socket_name) { 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AdbClientSocket::TransportQuery( 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) port, serial, socket_name, 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&HttpOverAdbSocket::OnSocketAvailable, 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(this))); 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OnSocketAvailable(int result, 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::StreamSocket* socket) { 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) socket_.reset(socket); 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<net::StringIOBuffer> request_buffer = 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new net::StringIOBuffer(request_); 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = socket_->Write( 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_buffer.get(), 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_buffer->size(), 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&HttpOverAdbSocket::ReadResponse, base::Unretained(this))); 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReadResponse(result); 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void ReadResponse(int result) { 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<net::IOBuffer> response_buffer = 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new net::IOBuffer(kBufferSize); 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = socket_->Read(response_buffer.get(), 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kBufferSize, 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&HttpOverAdbSocket::OnResponseData, 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) response_buffer, 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) -1)); 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnResponseData(response_buffer, -1, result); 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int bytes_total, 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result) { 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result == 0) { 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED); 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) response_ += std::string(response_buffer->data(), result); 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int expected_length = 0; 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (bytes_total < 0) { 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t content_pos = response_.find("Content-Length:"); 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (content_pos != std::string::npos) { 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t endline_pos = response_.find("\n", content_pos); 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (endline_pos != std::string::npos) { 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string len = response_.substr(content_pos + 15, 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) endline_pos - content_pos - 15); 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TrimWhitespace(len, base::TRIM_ALL, &len); 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!base::StringToInt(len, &expected_length)) { 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CheckNetResultOrDie(net::ERR_FAILED); 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) body_pos_ = response_.find("\r\n\r\n"); 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (body_pos_ != std::string::npos) { 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) body_pos_ += 4; 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bytes_total = body_pos_ + expected_length; 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (bytes_total == static_cast<int>(response_.length())) { 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!command_callback_.is_null()) 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) command_callback_.Run(body_pos_, response_); 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) socket_callback_.Run(net::OK, socket_.release()); 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete this; 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = socket_->Read(response_buffer.get(), 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kBufferSize, 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&HttpOverAdbSocket::OnResponseData, 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) response_buffer, 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bytes_total)); 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnResponseData(response_buffer, bytes_total, result); 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool CheckNetResultOrDie(int result) { 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result >= 0) 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!command_callback_.is_null()) 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) command_callback_.Run(result, std::string()); 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) socket_callback_.Run(result, NULL); 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete this; 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<net::StreamSocket> socket_; 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string request_; 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string response_; 23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CommandCallback command_callback_; 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SocketCallback socket_callback_; 23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t body_pos_; 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class AdbQuerySocket : AdbClientSocket { 24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AdbQuerySocket(int port, 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& query, 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CommandCallback& callback) 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : AdbClientSocket(port), 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) current_query_(0), 24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_(callback) { 24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (Tokenize(query, "|", &queries_) == 0) { 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CheckNetResultOrDie(net::ERR_INVALID_ARGUMENT); 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Connect(base::Bind(&AdbQuerySocket::SendNextQuery, 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(this))); 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ~AdbQuerySocket() { 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SendNextQuery(int result) { 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!CheckNetResultOrDie(result)) 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string query = queries_[current_query_]; 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (query.length() > 0xFFFF) { 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CheckNetResultOrDie(net::ERR_MSG_TOO_BIG); 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_void = current_query_ < queries_.size() - 1; 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SendCommand(query, is_void, 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&AdbQuerySocket::OnResponse, base::Unretained(this))); 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OnResponse(int result, const std::string& response) { 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (++current_query_ < queries_.size()) { 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SendNextQuery(net::OK); 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_.Run(result, response); 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete this; 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool CheckNetResultOrDie(int result) { 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result >= 0) 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_.Run(result, std::string()); 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delete this; 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<std::string> queries_; 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t current_query_; 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CommandCallback callback_; 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::AdbQuery(int port, 29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& query, 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CommandCallback& callback) { 30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new AdbQuerySocket(port, query, callback); 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(DEBUG_DEVTOOLS) 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void UseTransportQueryForDesktop(const SocketCallback& callback, 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::StreamSocket* socket, 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result) { 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(result, socket); 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif // defined(DEBUG_DEVTOOLS) 31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::TransportQuery(int port, 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& serial, 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& socket_name, 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SocketCallback& callback) { 31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(DEBUG_DEVTOOLS) 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (serial.empty()) { 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Use plain socket for remote debugging on Desktop (debugging purposes). 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::IPAddressNumber ip_number; 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::ParseIPLiteralToNumber(kLocalhost, &ip_number); 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int tcp_port = 0; 32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!base::StringToInt(socket_name, &tcp_port)) 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tcp_port = 9222; 32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::AddressList address_list = 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::AddressList::CreateFromIPAddress(ip_number, tcp_port); 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::TCPClientSocket* socket = new net::TCPClientSocket( 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) address_list, NULL, net::NetLog::Source()); 33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) socket->Connect(base::Bind(&UseTransportQueryForDesktop, callback, socket)); 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif // defined(DEBUG_DEVTOOLS) 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new AdbTransportSocket(port, serial, socket_name, callback); 33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::HttpQuery(int port, 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& serial, 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& socket_name, 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& request_path, 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CommandCallback& callback) { 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new HttpOverAdbSocket(port, serial, socket_name, request_path, 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback); 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::HttpQuery(int port, 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& serial, 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& socket_name, 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& request_path, 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SocketCallback& callback) { 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new HttpOverAdbSocket(port, serial, socket_name, request_path, 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback); 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)AdbClientSocket::AdbClientSocket(int port) 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : host_(kLocalhost), port_(port) { 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)AdbClientSocket::~AdbClientSocket() { 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::Connect(const net::CompletionCallback& callback) { 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::IPAddressNumber ip_number; 36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!net::ParseIPLiteralToNumber(host_, &ip_number)) { 36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(net::ERR_FAILED); 36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::AddressList address_list = 37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::AddressList::CreateFromIPAddress(ip_number, port_); 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) socket_.reset(new net::TCPClientSocket(address_list, NULL, 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::NetLog::Source())); 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result = socket_->Connect(callback); 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(result); 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::SendCommand(const std::string& command, 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_void, 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CommandCallback& callback) { 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<net::StringIOBuffer> request_buffer = 38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new net::StringIOBuffer(EncodeMessage(command)); 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = socket_->Write(request_buffer.get(), 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_buffer->size(), 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&AdbClientSocket::ReadResponse, 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback, 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) is_void)); 39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReadResponse(callback, is_void, result); 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::ReadResponse(const CommandCallback& callback, 39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_void, 39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result) { 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result < 0) { 40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(result, "IO error"); 40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<net::IOBuffer> response_buffer = 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new net::IOBuffer(kBufferSize); 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = socket_->Read(response_buffer.get(), 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kBufferSize, 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&AdbClientSocket::OnResponseHeader, 408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback, 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) is_void, 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) response_buffer)); 41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result != net::ERR_IO_PENDING) 41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnResponseHeader(callback, is_void, response_buffer, result); 41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::OnResponseHeader( 41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CommandCallback& callback, 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_void, 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<net::IOBuffer> response_buffer, 42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result) { 42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result <= 0) { 42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(result == 0 ? net::ERR_CONNECTION_CLOSED : result, 42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "IO error"); 42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string data = std::string(response_buffer->data(), result); 42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result < 4) { 42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(net::ERR_FAILED, "Response is too short: " + data); 43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string status = data.substr(0, 4); 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status != kOkayResponse) { 43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(net::ERR_FAILED, data); 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data = data.substr(4); 44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!is_void) { 44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int payload_length = 0; 44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int bytes_left = -1; 44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (data.length() >= 4 && 44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::HexStringToInt(data.substr(0, 4), &payload_length)) { 44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data = data.substr(4); 44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bytes_left = payload_length - result + 8; 44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bytes_left = -1; 45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 45190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnResponseData(callback, data, response_buffer, bytes_left, 0); 45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(net::OK, data); 45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AdbClientSocket::OnResponseData( 45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CommandCallback& callback, 45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& response, 46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<net::IOBuffer> response_buffer, 46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int bytes_left, 46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result) { 46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result < 0) { 46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(result, "IO error"); 46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bytes_left -= result; 46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string new_response = 47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) response + std::string(response_buffer->data(), result); 47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (bytes_left == 0) { 47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(net::OK, new_response); 47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Read tail 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result = socket_->Read(response_buffer.get(), 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kBufferSize, 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&AdbClientSocket::OnResponseData, 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this), 481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback, 482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new_response, 483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) response_buffer, 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bytes_left)); 48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result > 0) 48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnResponseData(callback, new_response, response_buffer, bytes_left, result); 48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else if (result != net::ERR_IO_PENDING) 48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(net::OK, new_response); 48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 490