Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4695)

Unified Diff: chrome/browser/devtools/adb_client_socket.cc

Issue 12559008: DevTools: add backend for discovering connected ADB devices. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Offline review comments addressed Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/devtools/adb_client_socket.h ('k') | chrome/browser/devtools/devtools_adb_bridge.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/devtools/adb_client_socket.cc
diff --git a/chrome/browser/devtools/adb_client_socket.cc b/chrome/browser/devtools/adb_client_socket.cc
new file mode 100644
index 0000000000000000000000000000000000000000..df1c258f34d52b9505d7834ded7ad02b52ddc0b1
--- /dev/null
+++ b/chrome/browser/devtools/adb_client_socket.cc
@@ -0,0 +1,161 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/devtools/adb_client_socket.h"
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
+#include "net/base/net_errors.h"
+
+namespace {
+
+const int kBufferSize = 16 * 1024;
+
+std::string EncodeLength(size_t length) {
+ static const char kHexChars[] = "0123456789ABCDEF";
+
+ std::string result(4, '\0');
+ char b = reinterpret_cast<const char*>(&length)[1];
+ result[0] = kHexChars[(b >> 4) & 0xf];
+ result[1] = kHexChars[b & 0xf];
+ b = reinterpret_cast<const char*>(&length)[0];
+ result[2] = kHexChars[(b >> 4) & 0xf];
+ result[3] = kHexChars[b & 0xf];
+ return result;
+}
+
+} // namespace
+
+// static
+void ADBClientSocket::Query(int port,
+ const std::string& query,
+ const Callback& callback) {
+ (new ADBClientSocket())->InnerQuery(port, query, callback);
+}
+
+ADBClientSocket::ADBClientSocket() : expected_response_length_(-1) {
+}
+
+ADBClientSocket::~ADBClientSocket() {
+}
+
+void ADBClientSocket::InnerQuery(int port,
+ const std::string& query,
+ const Callback& callback) {
+ if (query.length() > 0xFFFF) {
+ ReportErrorAndDie("Input message is too big");
+ return;
+ }
+ callback_ = callback;
+
+ net::IPAddressNumber ip_number;
+ if (!net::ParseIPLiteralToNumber("127.0.0.1", &ip_number)) {
+ ReportErrorAndDie("Could not connect to ADB");
+ return;
+ }
+
+ net::AddressList address_list =
+ net::AddressList::CreateFromIPAddress(ip_number, port);
+ socket_.reset(new net::TCPClientSocket(address_list, NULL,
+ net::NetLog::Source()));
+ std::string message = EncodeLength(query.length()) + query;
+ scoped_refptr<net::StringIOBuffer> request_buffer =
+ new net::StringIOBuffer(message);
+ int result = socket_->Connect(base::Bind(&ADBClientSocket::OnConnectComplete,
+ base::Unretained(this),
+ request_buffer));
+ if (result != net::ERR_IO_PENDING)
+ ReportErrorAndDie("Could not connect to ADB");
+}
+
+void ADBClientSocket::OnConnectComplete(
+ scoped_refptr<net::StringIOBuffer> request_buffer,
+ int result) {
+ if (!CheckNetResultOrDie(result))
+ return;
+ result = socket_->Write(request_buffer, request_buffer->size(),
+ base::Bind(&ADBClientSocket::OnWriteComplete, base::Unretained(this)));
+ if (result != net::ERR_IO_PENDING)
+ OnWriteComplete(result);
+}
+
+void ADBClientSocket::OnWriteComplete(int result) {
+ if (!CheckNetResultOrDie(result))
+ return;
+ scoped_refptr<net::IOBuffer> response_buffer =
+ new net::IOBuffer(kBufferSize);
+ result = socket_->Read(response_buffer, kBufferSize,
+ base::Bind(&ADBClientSocket::OnReadComplete, base::Unretained(this),
+ response_buffer));
+ if (result != net::ERR_IO_PENDING)
+ OnReadComplete(response_buffer, result);
+}
+
+void ADBClientSocket::OnReadComplete(
+ scoped_refptr<net::IOBuffer> response_buffer,
+ int result) {
+ if (!CheckNetResultOrDie(result))
+ return;
+
+ response_ += std::string(response_buffer->data(), result);
+ if (expected_response_length_ == -1) {
+ // Reading header
+ if (result < 8) {
+ ReportErrorAndDie("Response is too short: " + response_);
+ return;
+ }
+
+ std::string status = response_.substr(0, 4);
+ if (status != "OKAY" && status != "FAIL") {
+ ReportInvalidResponseAndDie();
+ return;
+ }
+ std::string payload_length = response_.substr(4, 4);
+ if (!base::HexStringToInt(response_.substr(4, 4),
+ &expected_response_length_)) {
+ ReportInvalidResponseAndDie();
+ return;
+ }
+ }
+
+ if (static_cast<int>(response_.length() - 8) == expected_response_length_) {
+ ReportSuccessAndDie();
+ return;
+ }
+
+ // Read tail
+ result = socket_->Read(response_buffer, kBufferSize,
+ base::Bind(&ADBClientSocket::OnReadComplete, base::Unretained(this),
+ response_buffer));
+ if (result != net::ERR_IO_PENDING)
+ OnReadComplete(response_buffer, result);
+}
+
+bool ADBClientSocket::CheckNetResultOrDie(int result) {
+ if (result >= 0)
+ return true;
+ ReportErrorAndDie(base::StringPrintf("Internal error %d", result));
+ return false;
+}
+
+void ADBClientSocket::ReportSuccessAndDie() {
+ callback_.Run(std::string(), response_.substr(8));
+ Destroy();
+}
+
+void ADBClientSocket::ReportInvalidResponseAndDie() {
+ callback_.Run("Invalid response: " + response_, std::string());
+ Destroy();
+}
+
+void ADBClientSocket::ReportErrorAndDie(const std::string& error) {
+ callback_.Run(error, std::string());
+ Destroy();
+}
+
+void ADBClientSocket::Destroy() {
+ delete this;
+}
« no previous file with comments | « chrome/browser/devtools/adb_client_socket.h ('k') | chrome/browser/devtools/devtools_adb_bridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698