| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/devtools/adb_client_socket.h" | 5 #include "chrome/browser/devtools/adb_client_socket.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 std::string result(4, '\0'); | 31 std::string result(4, '\0'); |
| 32 char b = reinterpret_cast<const char*>(&length)[1]; | 32 char b = reinterpret_cast<const char*>(&length)[1]; |
| 33 result[0] = kHexChars[(b >> 4) & 0xf]; | 33 result[0] = kHexChars[(b >> 4) & 0xf]; |
| 34 result[1] = kHexChars[b & 0xf]; | 34 result[1] = kHexChars[b & 0xf]; |
| 35 b = reinterpret_cast<const char*>(&length)[0]; | 35 b = reinterpret_cast<const char*>(&length)[0]; |
| 36 result[2] = kHexChars[(b >> 4) & 0xf]; | 36 result[2] = kHexChars[(b >> 4) & 0xf]; |
| 37 result[3] = kHexChars[b & 0xf]; | 37 result[3] = kHexChars[b & 0xf]; |
| 38 return result + message; | 38 return result + message; |
| 39 } | 39 } |
| 40 | 40 |
| 41 class AdbSocket { | 41 class AdbTransportSocket : public AdbClientSocket { |
| 42 public: | |
| 43 AdbSocket(const std::string& host, int port) : host_(host), port_(port) { | |
| 44 } | |
| 45 | |
| 46 ~AdbSocket() { | |
| 47 } | |
| 48 | |
| 49 protected: | |
| 50 void Connect(const net::CompletionCallback& callback) { | |
| 51 net::IPAddressNumber ip_number; | |
| 52 if (!net::ParseIPLiteralToNumber(host_, &ip_number)) { | |
| 53 callback.Run(net::ERR_FAILED); | |
| 54 return; | |
| 55 } | |
| 56 | |
| 57 net::AddressList address_list = | |
| 58 net::AddressList::CreateFromIPAddress(ip_number, port_); | |
| 59 socket_.reset(new net::TCPClientSocket(address_list, NULL, | |
| 60 net::NetLog::Source())); | |
| 61 int result = socket_->Connect(callback); | |
| 62 if (result != net::ERR_IO_PENDING) | |
| 63 callback.Run(result); | |
| 64 } | |
| 65 | |
| 66 void SendCommand(const std::string& command, | |
| 67 bool is_void, | |
| 68 const CommandCallback& callback) { | |
| 69 scoped_refptr<net::StringIOBuffer> request_buffer = | |
| 70 new net::StringIOBuffer(EncodeMessage(command)); | |
| 71 int result = socket_->Write(request_buffer, request_buffer->size(), | |
| 72 base::Bind(&AdbSocket::ReadResponse, base::Unretained(this), | |
| 73 callback, is_void)); | |
| 74 if (result != net::ERR_IO_PENDING) | |
| 75 ReadResponse(callback, is_void, result); | |
| 76 } | |
| 77 | |
| 78 scoped_ptr<net::TCPClientSocket> socket_; | |
| 79 | |
| 80 private: | |
| 81 void ReadResponse(const CommandCallback& callback, bool is_void, int result) { | |
| 82 if (result < 0) { | |
| 83 callback.Run(result, "IO error"); | |
| 84 return; | |
| 85 } | |
| 86 scoped_refptr<net::IOBuffer> response_buffer = | |
| 87 new net::IOBuffer(kBufferSize); | |
| 88 result = socket_->Read(response_buffer, kBufferSize, | |
| 89 base::Bind(&AdbSocket::OnResponseHeader, base::Unretained(this), | |
| 90 callback, is_void, response_buffer)); | |
| 91 if (result != net::ERR_IO_PENDING) | |
| 92 OnResponseHeader(callback, is_void, response_buffer, result); | |
| 93 } | |
| 94 | |
| 95 void OnResponseHeader(const CommandCallback& callback, | |
| 96 bool is_void, | |
| 97 scoped_refptr<net::IOBuffer> response_buffer, | |
| 98 int result) { | |
| 99 if (result < 0) { | |
| 100 callback.Run(result, "IO error"); | |
| 101 return; | |
| 102 } | |
| 103 | |
| 104 std::string data = std::string(response_buffer->data(), result); | |
| 105 if (result < 4) { | |
| 106 callback.Run(net::ERR_FAILED, "Response is too short: " + data); | |
| 107 return; | |
| 108 } | |
| 109 | |
| 110 std::string status = data.substr(0, 4); | |
| 111 if (status != kOkayResponse) { | |
| 112 callback.Run(net::ERR_FAILED, data); | |
| 113 return; | |
| 114 } | |
| 115 | |
| 116 data = data.substr(4); | |
| 117 | |
| 118 if (!is_void) { | |
| 119 int payload_length = 0; | |
| 120 int bytes_left = -1; | |
| 121 if (data.length() >= 4 && | |
| 122 base::HexStringToInt(data.substr(0, 4), &payload_length)) { | |
| 123 data = data.substr(4); | |
| 124 bytes_left = payload_length - result + 8; | |
| 125 } else { | |
| 126 bytes_left = -1; | |
| 127 } | |
| 128 OnResponseData(callback, data, response_buffer, bytes_left, 0); | |
| 129 } else { | |
| 130 callback.Run(net::OK, data); | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 void OnResponseData(const CommandCallback& callback, | |
| 135 const std::string& response, | |
| 136 scoped_refptr<net::IOBuffer> response_buffer, | |
| 137 int bytes_left, | |
| 138 int result) { | |
| 139 if (result < 0) { | |
| 140 callback.Run(result, "IO error"); | |
| 141 return; | |
| 142 } | |
| 143 | |
| 144 bytes_left -= result; | |
| 145 std::string new_response = | |
| 146 response + std::string(response_buffer->data(), result); | |
| 147 if (bytes_left == 0) { | |
| 148 callback.Run(net::OK, new_response); | |
| 149 return; | |
| 150 } | |
| 151 | |
| 152 // Read tail | |
| 153 result = socket_->Read(response_buffer, kBufferSize, | |
| 154 base::Bind(&AdbSocket::OnResponseData, base::Unretained(this), | |
| 155 callback, new_response, response_buffer, bytes_left)); | |
| 156 if (result > 0) { | |
| 157 OnResponseData(callback, new_response, response_buffer, bytes_left, | |
| 158 result); | |
| 159 } else if (result != net::ERR_IO_PENDING) { | |
| 160 callback.Run(net::OK, new_response); | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 std::string host_; | |
| 165 int port_; | |
| 166 }; | |
| 167 | |
| 168 class AdbTransportSocket : public AdbSocket { | |
| 169 public: | 42 public: |
| 170 AdbTransportSocket(const std::string& host, | 43 AdbTransportSocket(const std::string& host, |
| 171 int port, | 44 int port, |
| 172 const std::string& serial, | 45 const std::string& serial, |
| 173 const std::string& socket_name, | 46 const std::string& socket_name, |
| 174 const SocketCallback& callback) | 47 const SocketCallback& callback) |
| 175 : AdbSocket(host, port), | 48 : AdbClientSocket(host, port), |
| 176 serial_(serial), | 49 serial_(serial), |
| 177 socket_name_(socket_name), | 50 socket_name_(socket_name), |
| 178 callback_(callback) { | 51 callback_(callback) { |
| 179 Connect(base::Bind(&AdbTransportSocket::OnConnected, | 52 Connect(base::Bind(&AdbTransportSocket::OnConnected, |
| 180 base::Unretained(this))); | 53 base::Unretained(this))); |
| 181 } | 54 } |
| 182 | 55 |
| 183 private: | 56 private: |
| 184 ~AdbTransportSocket() {} | 57 ~AdbTransportSocket() {} |
| 185 | 58 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 response_buffer, -1)); | 160 response_buffer, -1)); |
| 288 if (result != net::ERR_IO_PENDING) | 161 if (result != net::ERR_IO_PENDING) |
| 289 OnResponseData(response_buffer, -1, result); | 162 OnResponseData(response_buffer, -1, result); |
| 290 } | 163 } |
| 291 | 164 |
| 292 void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, | 165 void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer, |
| 293 int bytes_total, | 166 int bytes_total, |
| 294 int result) { | 167 int result) { |
| 295 if (!CheckNetResultOrDie(result)) | 168 if (!CheckNetResultOrDie(result)) |
| 296 return; | 169 return; |
| 170 if (result == 0) { |
| 171 CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED); |
| 172 return; |
| 173 } |
| 297 | 174 |
| 298 response_ += std::string(response_buffer->data(), result); | 175 response_ += std::string(response_buffer->data(), result); |
| 299 int expected_length = 0; | 176 int expected_length = 0; |
| 300 if (bytes_total < 0) { | 177 if (bytes_total < 0) { |
| 301 size_t content_pos = response_.find("Content-Length:"); | 178 size_t content_pos = response_.find("Content-Length:"); |
| 302 if (content_pos != std::string::npos) { | 179 if (content_pos != std::string::npos) { |
| 303 size_t endline_pos = response_.find("\n", content_pos); | 180 size_t endline_pos = response_.find("\n", content_pos); |
| 304 if (endline_pos != std::string::npos) { | 181 if (endline_pos != std::string::npos) { |
| 305 std::string len = response_.substr(content_pos + 15, | 182 std::string len = response_.substr(content_pos + 15, |
| 306 endline_pos - content_pos - 15); | 183 endline_pos - content_pos - 15); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 } | 224 } |
| 348 | 225 |
| 349 scoped_ptr<net::TCPClientSocket> socket_; | 226 scoped_ptr<net::TCPClientSocket> socket_; |
| 350 std::string request_; | 227 std::string request_; |
| 351 std::string response_; | 228 std::string response_; |
| 352 CommandCallback command_callback_; | 229 CommandCallback command_callback_; |
| 353 SocketCallback socket_callback_; | 230 SocketCallback socket_callback_; |
| 354 size_t body_pos_; | 231 size_t body_pos_; |
| 355 }; | 232 }; |
| 356 | 233 |
| 357 class AdbQuerySocket : AdbSocket { | 234 class AdbQuerySocket : AdbClientSocket { |
| 358 public: | 235 public: |
| 359 AdbQuerySocket(const std::string& host, | 236 AdbQuerySocket(const std::string& host, |
| 360 int port, | 237 int port, |
| 361 const std::string& query, | 238 const std::string& query, |
| 362 const CommandCallback& callback) | 239 const CommandCallback& callback) |
| 363 : AdbSocket(host, port), | 240 : AdbClientSocket(host, port), |
| 364 current_query_(0), | 241 current_query_(0), |
| 365 callback_(callback) { | 242 callback_(callback) { |
| 366 if (Tokenize(query, "|", &queries_) == 0) { | 243 if (Tokenize(query, "|", &queries_) == 0) { |
| 367 CheckNetResultOrDie(net::ERR_INVALID_ARGUMENT); | 244 CheckNetResultOrDie(net::ERR_INVALID_ARGUMENT); |
| 368 return; | 245 return; |
| 369 } | 246 } |
| 370 Connect(base::Bind(&AdbQuerySocket::SendNextQuery, | 247 Connect(base::Bind(&AdbQuerySocket::SendNextQuery, |
| 371 base::Unretained(this))); | 248 base::Unretained(this))); |
| 372 } | 249 } |
| 373 | 250 |
| 374 private: | 251 private: |
| 375 ~AdbQuerySocket() { | 252 ~AdbQuerySocket() { |
| 376 | |
| 377 } | 253 } |
| 378 | 254 |
| 379 void SendNextQuery(int result) { | 255 void SendNextQuery(int result) { |
| 380 if (!CheckNetResultOrDie(result)) | 256 if (!CheckNetResultOrDie(result)) |
| 381 return; | 257 return; |
| 382 std::string query = queries_[current_query_]; | 258 std::string query = queries_[current_query_]; |
| 383 if (query.length() > 0xFFFF) { | 259 if (query.length() > 0xFFFF) { |
| 384 CheckNetResultOrDie(net::ERR_MSG_TOO_BIG); | 260 CheckNetResultOrDie(net::ERR_MSG_TOO_BIG); |
| 385 return; | 261 return; |
| 386 } | 262 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 // static | 309 // static |
| 434 void AdbClientSocket::HttpQuery(int port, | 310 void AdbClientSocket::HttpQuery(int port, |
| 435 const std::string& serial, | 311 const std::string& serial, |
| 436 const std::string& socket_name, | 312 const std::string& socket_name, |
| 437 const std::string& request_path, | 313 const std::string& request_path, |
| 438 const SocketCallback& callback) { | 314 const SocketCallback& callback) { |
| 439 new HttpOverAdbSocket(kLocalhost, port, serial, socket_name, request_path, | 315 new HttpOverAdbSocket(kLocalhost, port, serial, socket_name, request_path, |
| 440 callback); | 316 callback); |
| 441 } | 317 } |
| 442 | 318 |
| 443 AdbClientSocket::AdbClientSocket() { | 319 AdbClientSocket::AdbClientSocket(const std::string& host, int port) |
| 320 : host_(host), port_(port) { |
| 444 } | 321 } |
| 445 | 322 |
| 446 AdbClientSocket::~AdbClientSocket() { | 323 AdbClientSocket::~AdbClientSocket() { |
| 447 } | 324 } |
| 325 |
| 326 void AdbClientSocket::Connect(const net::CompletionCallback& callback) { |
| 327 net::IPAddressNumber ip_number; |
| 328 if (!net::ParseIPLiteralToNumber(host_, &ip_number)) { |
| 329 callback.Run(net::ERR_FAILED); |
| 330 return; |
| 331 } |
| 332 |
| 333 net::AddressList address_list = |
| 334 net::AddressList::CreateFromIPAddress(ip_number, port_); |
| 335 socket_.reset(new net::TCPClientSocket(address_list, NULL, |
| 336 net::NetLog::Source())); |
| 337 int result = socket_->Connect(callback); |
| 338 if (result != net::ERR_IO_PENDING) |
| 339 callback.Run(result); |
| 340 } |
| 341 |
| 342 void AdbClientSocket::SendCommand(const std::string& command, |
| 343 bool is_void, |
| 344 const CommandCallback& callback) { |
| 345 scoped_refptr<net::StringIOBuffer> request_buffer = |
| 346 new net::StringIOBuffer(EncodeMessage(command)); |
| 347 int result = socket_->Write(request_buffer, request_buffer->size(), |
| 348 base::Bind(&AdbClientSocket::ReadResponse, base::Unretained(this), |
| 349 callback, is_void)); |
| 350 if (result != net::ERR_IO_PENDING) |
| 351 ReadResponse(callback, is_void, result); |
| 352 } |
| 353 |
| 354 void AdbClientSocket::ReadResponse(const CommandCallback& callback, |
| 355 bool is_void, |
| 356 int result) { |
| 357 if (result < 0) { |
| 358 callback.Run(result, "IO error"); |
| 359 return; |
| 360 } |
| 361 scoped_refptr<net::IOBuffer> response_buffer = |
| 362 new net::IOBuffer(kBufferSize); |
| 363 result = socket_->Read(response_buffer, kBufferSize, |
| 364 base::Bind(&AdbClientSocket::OnResponseHeader, base::Unretained(this), |
| 365 callback, is_void, response_buffer)); |
| 366 if (result != net::ERR_IO_PENDING) |
| 367 OnResponseHeader(callback, is_void, response_buffer, result); |
| 368 } |
| 369 |
| 370 void AdbClientSocket::OnResponseHeader( |
| 371 const CommandCallback& callback, |
| 372 bool is_void, |
| 373 scoped_refptr<net::IOBuffer> response_buffer, |
| 374 int result) { |
| 375 if (result <= 0) { |
| 376 callback.Run(result == 0 ? net::ERR_CONNECTION_CLOSED : result, |
| 377 "IO error"); |
| 378 return; |
| 379 } |
| 380 |
| 381 std::string data = std::string(response_buffer->data(), result); |
| 382 if (result < 4) { |
| 383 callback.Run(net::ERR_FAILED, "Response is too short: " + data); |
| 384 return; |
| 385 } |
| 386 |
| 387 std::string status = data.substr(0, 4); |
| 388 if (status != kOkayResponse) { |
| 389 callback.Run(net::ERR_FAILED, data); |
| 390 return; |
| 391 } |
| 392 |
| 393 data = data.substr(4); |
| 394 |
| 395 if (!is_void) { |
| 396 int payload_length = 0; |
| 397 int bytes_left = -1; |
| 398 if (data.length() >= 4 && |
| 399 base::HexStringToInt(data.substr(0, 4), &payload_length)) { |
| 400 data = data.substr(4); |
| 401 bytes_left = payload_length - result + 8; |
| 402 } else { |
| 403 bytes_left = -1; |
| 404 } |
| 405 OnResponseData(callback, data, response_buffer, bytes_left, 0); |
| 406 } else { |
| 407 callback.Run(net::OK, data); |
| 408 } |
| 409 } |
| 410 |
| 411 void AdbClientSocket::OnResponseData( |
| 412 const CommandCallback& callback, |
| 413 const std::string& response, |
| 414 scoped_refptr<net::IOBuffer> response_buffer, |
| 415 int bytes_left, |
| 416 int result) { |
| 417 if (result < 0) { |
| 418 callback.Run(result, "IO error"); |
| 419 return; |
| 420 } |
| 421 |
| 422 bytes_left -= result; |
| 423 std::string new_response = |
| 424 response + std::string(response_buffer->data(), result); |
| 425 if (bytes_left == 0) { |
| 426 callback.Run(net::OK, new_response); |
| 427 return; |
| 428 } |
| 429 |
| 430 // Read tail |
| 431 result = socket_->Read(response_buffer, kBufferSize, |
| 432 base::Bind(&AdbClientSocket::OnResponseData, base::Unretained(this), |
| 433 callback, new_response, response_buffer, bytes_left)); |
| 434 if (result > 0) |
| 435 OnResponseData(callback, new_response, response_buffer, bytes_left, result); |
| 436 else if (result != net::ERR_IO_PENDING) |
| 437 callback.Run(net::OK, new_response); |
| 438 } |
| OLD | NEW |