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