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.
5 #include "chrome/browser/devtools/adb/android_usb_socket.h"
7 #include "base/message_loop/message_loop.h"
11 const int kMaxPayload = 4096;
15 AndroidUsbSocket::IORequest::IORequest(
16 net::IOBuffer* buffer,
18 const net::CompletionCallback& callback)
24 AndroidUsbSocket::IORequest::~IORequest() {
27 AndroidUsbSocket::AndroidUsbSocket(scoped_refptr<AndroidUsbDevice> device,
29 const std::string& command,
30 base::Callback<void(uint32)> delete_callback)
33 delete_callback_(delete_callback),
40 AndroidUsbSocket::~AndroidUsbSocket() {
41 DCHECK(CalledOnValidThread());
44 delete_callback_.Run(local_id_);
47 void AndroidUsbSocket::HandleIncoming(scoped_refptr<AdbMessage> message) {
48 CHECK_EQ(message->arg1, local_id_);
49 switch (message->command) {
50 case AdbMessage::kCommandOKAY:
52 remote_id_ = message->arg0;
54 net::CompletionCallback callback = connect_callback_;
55 connect_callback_.Reset();
56 callback.Run(net::OK);
57 // "this" can be NULL.
60 // "this" can be NULL.
63 case AdbMessage::kCommandWRTE:
64 device_->Send(AdbMessage::kCommandOKAY, local_id_, message->arg0, "");
65 read_buffer_ += message->body;
66 // Allow WRTE over new connection even though OKAY ack was not received.
68 remote_id_ = message->arg0;
70 net::CompletionCallback callback = connect_callback_;
71 connect_callback_.Reset();
72 callback.Run(net::OK);
73 // "this" can be NULL.
75 RespondToReaders(false);
76 // "this" can be NULL.
79 case AdbMessage::kCommandCLSE:
81 device_->Send(AdbMessage::kCommandCLSE, local_id_, 0, "");
82 is_connected_ = false;
84 RespondToReaders(true);
85 // "this" can be NULL.
92 void AndroidUsbSocket::Terminated() {
93 is_connected_ = false;
95 if (!connect_callback_.is_null()) {
96 net::CompletionCallback callback = connect_callback_;
97 connect_callback_.Reset();
98 callback.Run(net::ERR_FAILED);
99 // "this" can be NULL.
102 RespondToReaders(true);
105 int AndroidUsbSocket::Read(net::IOBuffer* buffer,
107 const net::CompletionCallback& callback) {
109 return is_closed_ ? 0 : net::ERR_SOCKET_NOT_CONNECTED;
111 if (read_buffer_.empty()) {
112 read_requests_.push_back(IORequest(buffer, length, callback));
113 return net::ERR_IO_PENDING;
116 size_t bytes_to_copy = static_cast<size_t>(length) > read_buffer_.length() ?
117 read_buffer_.length() : static_cast<size_t>(length);
118 memcpy(buffer->data(), read_buffer_.data(), bytes_to_copy);
119 if (read_buffer_.length() > bytes_to_copy)
120 read_buffer_ = read_buffer_.substr(bytes_to_copy);
126 int AndroidUsbSocket::Write(net::IOBuffer* buffer,
128 const net::CompletionCallback& callback) {
130 return net::ERR_SOCKET_NOT_CONNECTED;
132 if (length > kMaxPayload)
133 length = kMaxPayload;
134 write_requests_.push_back(IORequest(NULL, length, callback));
135 device_->Send(AdbMessage::kCommandWRTE, local_id_, remote_id_,
136 std::string(buffer->data(), length));
137 return net::ERR_IO_PENDING;
140 bool AndroidUsbSocket::SetReceiveBufferSize(int32 size) {
145 bool AndroidUsbSocket::SetSendBufferSize(int32 size) {
150 int AndroidUsbSocket::Connect(const net::CompletionCallback& callback) {
151 DCHECK(CalledOnValidThread());
152 if (device_->terminated())
153 return net::ERR_FAILED;
154 connect_callback_ = callback;
155 device_->Send(AdbMessage::kCommandOPEN, local_id_, 0, command_);
156 return net::ERR_IO_PENDING;
159 void AndroidUsbSocket::Disconnect() {
160 is_connected_ = false;
161 device_->Send(AdbMessage::kCommandCLSE, local_id_, remote_id_, "");
162 RespondToReaders(true);
165 bool AndroidUsbSocket::IsConnected() const {
166 DCHECK(CalledOnValidThread());
167 return is_connected_;
170 bool AndroidUsbSocket::IsConnectedAndIdle() const {
175 int AndroidUsbSocket::GetPeerAddress(net::IPEndPoint* address) const {
176 net::IPAddressNumber ip(net::kIPv4AddressSize);
177 *address = net::IPEndPoint(ip, 0);
181 int AndroidUsbSocket::GetLocalAddress(net::IPEndPoint* address) const {
183 return net::ERR_FAILED;
186 const net::BoundNetLog& AndroidUsbSocket::NetLog() const {
190 void AndroidUsbSocket::SetSubresourceSpeculation() {
194 void AndroidUsbSocket::SetOmniboxSpeculation() {
198 bool AndroidUsbSocket::WasEverUsed() const {
203 bool AndroidUsbSocket::UsingTCPFastOpen() const {
208 bool AndroidUsbSocket::WasNpnNegotiated() const {
213 net::NextProto AndroidUsbSocket::GetNegotiatedProtocol() const {
215 return net::kProtoUnknown;
218 bool AndroidUsbSocket::GetSSLInfo(net::SSLInfo* ssl_info) {
222 void AndroidUsbSocket::RespondToReaders(bool disconnect) {
223 std::deque<IORequest> read_requests;
224 read_requests.swap(read_requests_);
225 while (!read_requests.empty() && (!read_buffer_.empty() || disconnect)) {
226 IORequest read_request = read_requests.front();
227 read_requests.pop_front();
228 size_t bytes_to_copy =
229 static_cast<size_t>(read_request.length) > read_buffer_.length() ?
230 read_buffer_.length() : static_cast<size_t>(read_request.length);
231 memcpy(read_request.buffer->data(), read_buffer_.data(), bytes_to_copy);
232 if (read_buffer_.length() > bytes_to_copy)
233 read_buffer_ = read_buffer_.substr(bytes_to_copy);
236 read_request.callback.Run(bytes_to_copy);
240 void AndroidUsbSocket::RespondToWriters() {
241 if (!write_requests_.empty()) {
242 IORequest write_request = write_requests_.front();
243 write_requests_.pop_front();
244 write_request.callback.Run(write_request.length);