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

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: 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 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) {
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 }
41
42 ADBClientSocket::~ADBClientSocket() {
43 }
44
45 void ADBClientSocket::InnerQuery(int port,
46 const std::string& query,
47 const Callback& callback) {
48 if (query.length() > 0xFFFF) {
49 ReportErrorAndDie("Input message is too big");
50 return;
51 }
52 callback_ = callback;
53
54 net::IPAddressNumber ip_number;
55 if (!net::ParseIPLiteralToNumber("127.0.0.1", &ip_number)) {
56 ReportErrorAndDie("Could not connect to ADB");
57 return;
58 }
59
60 net::AddressList address_list =
61 net::AddressList::CreateFromIPAddress(ip_number, port);
62 socket_.reset(new net::TCPClientSocket(address_list, NULL,
63 net::NetLog::Source()));
64 std::string message = EncodeLength(query.length()) + query;
65 scoped_refptr<net::StringIOBuffer> request_buffer =
66 new net::StringIOBuffer(message);
67 int result = socket_->Connect(base::Bind(&ADBClientSocket::OnConnectComplete,
68 base::Unretained(this),
69 request_buffer));
70 if (result != net::ERR_IO_PENDING)
71 ReportErrorAndDie("Could not connect to ADB");
72 }
73
74 void ADBClientSocket::OnConnectComplete(
75 scoped_refptr<net::StringIOBuffer> request_buffer,
76 int result) {
77 if (!CheckNetResultOrDie(result))
78 return;
79 result = socket_->Write(request_buffer, request_buffer->size(),
80 base::Bind(&ADBClientSocket::OnWriteComplete, base::Unretained(this)));
81 if (result != net::ERR_IO_PENDING)
82 OnWriteComplete(result);
83 }
84
85 void ADBClientSocket::OnWriteComplete(int result) {
86 if (!CheckNetResultOrDie(result))
87 return;
88 scoped_refptr<net::IOBuffer> response_buffer =
89 new net::IOBuffer(kBufferSize);
90 result = socket_->Read(response_buffer, kBufferSize,
91 base::Bind(&ADBClientSocket::OnReadComplete, base::Unretained(this),
92 response_buffer));
93 if (result != net::ERR_IO_PENDING)
94 OnReadComplete(response_buffer, result);
95 }
96
97 void ADBClientSocket::OnReadComplete(
98 scoped_refptr<net::IOBuffer> response_buffer,
99 int result) {
100 if (!CheckNetResultOrDie(result))
101 return;
102
103 response_ += std::string(response_buffer->data(), result);
104 if (expected_response_length_ == -1) {
105 // Reading header
106 if (result < 8) {
107 ReportErrorAndDie("Response is too short: " + response_);
108 return;
109 }
110
111 std::string status = response_.substr(0, 4);
112 if (status != "OKAY" && status != "FAIL") {
113 ReportInvalidResponseAndDie();
114 return;
115 }
116 std::string payload_length = response_.substr(4, 4);
117 if (!base::HexStringToInt(response_.substr(4, 4),
118 &expected_response_length_)) {
119 ReportInvalidResponseAndDie();
120 return;
121 }
122 }
123
124 if (static_cast<int>(response_.length() - 8) == expected_response_length_) {
125 ReportSuccessAndDie();
126 return;
127 }
128
129 // Read tail
130 result = socket_->Read(response_buffer, kBufferSize,
131 base::Bind(&ADBClientSocket::OnReadComplete, base::Unretained(this),
132 response_buffer));
133 if (result != net::ERR_IO_PENDING)
134 OnReadComplete(response_buffer, result);
135 }
136
137 bool ADBClientSocket::CheckNetResultOrDie(int result) {
138 if (result >= 0)
139 return true;
140 ReportErrorAndDie(base::StringPrintf("Internal error %d", result));
141 return false;
142 }
143
144 void ADBClientSocket::ReportSuccessAndDie() {
145 callback_.Run(std::string(), response_.substr(8));
146 Destroy();
147 }
148
149 void ADBClientSocket::ReportInvalidResponseAndDie() {
150 callback_.Run("Invalid response: " + response_, std::string());
151 Destroy();
152 }
153
154 void ADBClientSocket::ReportErrorAndDie(const std::string& error) {
155 callback_.Run(error, std::string());
156 Destroy();
157 }
158
159 void ADBClientSocket::Destroy() {
160 delete this;
161 }
OLDNEW
« 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