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

Side by Side 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: Same with Fetch for fetching discovery pages. 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/devtools/adb_client_socket.h"
6
7 #include "base/bind.h"
8 #include "base/compiler_specific.h"
9 #include "base/stringprintf.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "net/base/net_errors.h"
12
13 namespace {
14
15 const int kBufferSize = 16 * 1024;
16
17 std::string EncodeLength(size_t length) {
vsevik 2013/03/11 11:47:14 HexEncode(&length, 2);
18 static const char kHexChars[] = "0123456789ABCDEF";
19
20 std::string result(4, '\0');
21 char b = reinterpret_cast<const char*>(&length)[1];
22 result[0] = kHexChars[(b >> 4) & 0xf];
23 result[1] = kHexChars[b & 0xf];
24 b = reinterpret_cast<const char*>(&length)[0];
25 result[2] = kHexChars[(b >> 4) & 0xf];
26 result[3] = kHexChars[b & 0xf];
27 return result;
28 }
29
30 } // namespace
31
32 // static
33 void ADBClientSocket::Query(int port,
34 const std::string& query,
35 const Callback& callback) {
36 (new ADBClientSocket())->InnerQuery(port, query, callback);
37 }
38
39 ADBClientSocket::ADBClientSocket() : expected_response_length_(-1) {
40 AddRef(); // Balanced in *AndDie
41 }
42
43 ADBClientSocket::~ADBClientSocket() {
44 }
45
46 void ADBClientSocket::InnerQuery(int port,
47 const std::string& query,
48 const Callback& callback) {
49 if (query.length() > 0xFFFF) {
50 ReportErrorAndDie("Input message is too big");
51 return;
52 }
53 callback_ = callback;
54
55 net::IPAddressNumber ip_number;
56 if (!net::ParseIPLiteralToNumber("127.0.0.1", &ip_number)) {
57 ReportErrorAndDie("Could not connect to ADB");
58 return;
59 }
60
61 net::AddressList address_list =
62 net::AddressList::CreateFromIPAddress(ip_number, port);
63 socket_.reset(new net::TCPClientSocket(address_list, NULL,
64 net::NetLog::Source()));
65 std::string message = EncodeLength(query.length()) + query;
66 scoped_refptr<net::StringIOBuffer> request_buffer =
67 new net::StringIOBuffer(message);
68 int result = socket_->Connect(base::Bind(
69 &ADBClientSocket::OnConnectComplete, base::Unretained(this),
70 request_buffer));
71 if (result != net::ERR_IO_PENDING)
72 ReportErrorAndDie("Could not connect to ADB");
73 }
74
75 void ADBClientSocket::OnConnectComplete(
76 scoped_refptr<net::StringIOBuffer> request_buffer,
77 int result) {
78 if (!CheckNetResultOrDie(result))
79 return;
80 result = socket_->Write(request_buffer, request_buffer->size(),
81 base::Bind(&ADBClientSocket::OnWriteComplete, base::Unretained(this)));
82 if (result != net::ERR_IO_PENDING)
83 OnWriteComplete(result);
84 }
85
86 void ADBClientSocket::OnWriteComplete(int result) {
87 if (!CheckNetResultOrDie(result))
88 return;
89 scoped_refptr<net::IOBuffer> response_buffer =
90 new net::IOBuffer(kBufferSize);
91 result = socket_->Read(response_buffer, kBufferSize,
92 base::Bind(&ADBClientSocket::OnReadComplete, base::Unretained(this),
93 response_buffer));
94 if (result != net::ERR_IO_PENDING)
95 OnReadComplete(response_buffer, result);
96 }
97
98 void ADBClientSocket::OnReadComplete(
99 scoped_refptr<net::IOBuffer> response_buffer,
100 int result) {
101 if (!CheckNetResultOrDie(result))
102 return;
103
104 response_ += std::string(response_buffer->data(), result);
105 if (expected_response_length_ == -1) {
106 // Reading header
107 if (result < 8) {
108 ReportErrorAndDie("Response is too short: " + response_);
109 return;
110 }
111
112 std::string status = response_.substr(0, 4);
113 if (status != "OKAY" && status != "FAIL") {
114 ReportInvalidResponseAndDie();
115 return;
116 }
117 std::string payload_length = response_.substr(4, 4);
118 if (!base::HexStringToInt(response_.substr(4, 4),
119 &expected_response_length_)) {
120 ReportInvalidResponseAndDie();
121 return;
122 }
123 }
124
125 if (static_cast<int>(response_.length() - 8) == expected_response_length_) {
126 ReportSuccessAndDie();
127 return;
128 }
129
130 // Read tail
131 result = socket_->Read(response_buffer, kBufferSize,
132 base::Bind(&ADBClientSocket::OnReadComplete, base::Unretained(this),
133 response_buffer));
134 if (result != net::ERR_IO_PENDING)
135 OnReadComplete(response_buffer, result);
136 }
137
138 bool ADBClientSocket::CheckNetResultOrDie(int result) {
139 if (result >= 0)
140 return true;
141 ReportErrorAndDie(base::StringPrintf("Internal error %d", result));
142 return false;
143 }
144
145 void ADBClientSocket::ReportSuccessAndDie() {
146 callback_.Run(std::string(), response_.substr(8, response_.length() - 8));
vsevik 2013/03/11 11:47:14 callback_.Run(std::string(), response_.substr(8));
147 Release(); // Balanced in the constructor.
148 }
149
150 void ADBClientSocket::ReportInvalidResponseAndDie() {
151 callback_.Run("Invalid response: " + response_, std::string());
152 Release(); // Balanced in the constructor.
153 }
154
155 void ADBClientSocket::ReportErrorAndDie(const std::string& error) {
156 callback_.Run(error, std::string());
157 Release(); // Balanced in the constructor.
158 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698