1 // Copyright 2014 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/device/usb/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),
36 is_connected_(false) {
39 AndroidUsbSocket::~AndroidUsbSocket() {
40 DCHECK(CalledOnValidThread());
43 if (!delete_callback_.is_null())
44 delete_callback_.Run(local_id_);
47 void AndroidUsbSocket::HandleIncoming(scoped_refptr<AdbMessage> message) {
51 CHECK_EQ(message->arg1, local_id_);
52 switch (message->command) {
53 case AdbMessage::kCommandOKAY:
55 remote_id_ = message->arg0;
57 net::CompletionCallback callback = connect_callback_;
58 connect_callback_.Reset();
59 callback.Run(net::OK);
60 // "this" can be NULL.
63 // "this" can be NULL.
66 case AdbMessage::kCommandWRTE:
67 device_->Send(AdbMessage::kCommandOKAY, local_id_, message->arg0, "");
68 read_buffer_ += message->body;
69 // Allow WRTE over new connection even though OKAY ack was not received.
71 remote_id_ = message->arg0;
73 net::CompletionCallback callback = connect_callback_;
74 connect_callback_.Reset();
75 callback.Run(net::OK);
76 // "this" can be NULL.
78 RespondToReaders(false);
79 // "this" can be NULL.
82 case AdbMessage::kCommandCLSE:
84 device_->Send(AdbMessage::kCommandCLSE, local_id_, 0, "");
86 // "this" can be NULL.
93 void AndroidUsbSocket::Terminated(bool closed_by_device) {
94 is_connected_ = false;
96 // Break the socket -> device connection, release the device.
97 delete_callback_.Run(local_id_);
98 delete_callback_.Reset();
101 if (!closed_by_device)
104 // Respond to pending callbacks.
105 if (!connect_callback_.is_null()) {
106 net::CompletionCallback callback = connect_callback_;
107 connect_callback_.Reset();
108 callback.Run(net::ERR_FAILED);
109 // "this" can be NULL.
112 RespondToReaders(true);
115 int AndroidUsbSocket::Read(net::IOBuffer* buffer,
117 const net::CompletionCallback& callback) {
119 return device_.get() ? net::ERR_SOCKET_NOT_CONNECTED : 0;
121 if (read_buffer_.empty()) {
122 read_requests_.push_back(IORequest(buffer, length, callback));
123 return net::ERR_IO_PENDING;
126 size_t bytes_to_copy = static_cast<size_t>(length) > read_buffer_.length() ?
127 read_buffer_.length() : static_cast<size_t>(length);
128 memcpy(buffer->data(), read_buffer_.data(), bytes_to_copy);
129 if (read_buffer_.length() > bytes_to_copy)
130 read_buffer_ = read_buffer_.substr(bytes_to_copy);
133 return bytes_to_copy;
136 int AndroidUsbSocket::Write(net::IOBuffer* buffer,
138 const net::CompletionCallback& callback) {
140 return net::ERR_SOCKET_NOT_CONNECTED;
142 if (length > kMaxPayload)
143 length = kMaxPayload;
144 write_requests_.push_back(IORequest(NULL, length, callback));
145 device_->Send(AdbMessage::kCommandWRTE, local_id_, remote_id_,
146 std::string(buffer->data(), length));
147 return net::ERR_IO_PENDING;
150 int AndroidUsbSocket::SetReceiveBufferSize(int32 size) {
152 return net::ERR_NOT_IMPLEMENTED;
155 int AndroidUsbSocket::SetSendBufferSize(int32 size) {
157 return net::ERR_NOT_IMPLEMENTED;
160 int AndroidUsbSocket::Connect(const net::CompletionCallback& callback) {
161 DCHECK(CalledOnValidThread());
163 return net::ERR_FAILED;
164 connect_callback_ = callback;
165 device_->Send(AdbMessage::kCommandOPEN, local_id_, 0, command_);
166 return net::ERR_IO_PENDING;
169 void AndroidUsbSocket::Disconnect() {
172 device_->Send(AdbMessage::kCommandCLSE, local_id_, remote_id_, "");
176 bool AndroidUsbSocket::IsConnected() const {
177 DCHECK(CalledOnValidThread());
178 return is_connected_;
181 bool AndroidUsbSocket::IsConnectedAndIdle() const {
186 int AndroidUsbSocket::GetPeerAddress(net::IPEndPoint* address) const {
187 net::IPAddressNumber ip(net::kIPv4AddressSize);
188 *address = net::IPEndPoint(ip, 0);
192 int AndroidUsbSocket::GetLocalAddress(net::IPEndPoint* address) const {
194 return net::ERR_NOT_IMPLEMENTED;
197 const net::BoundNetLog& AndroidUsbSocket::NetLog() const {
201 void AndroidUsbSocket::SetSubresourceSpeculation() {
205 void AndroidUsbSocket::SetOmniboxSpeculation() {
209 bool AndroidUsbSocket::WasEverUsed() const {
214 bool AndroidUsbSocket::UsingTCPFastOpen() const {
219 bool AndroidUsbSocket::WasNpnNegotiated() const {
224 net::NextProto AndroidUsbSocket::GetNegotiatedProtocol() const {
226 return net::kProtoUnknown;
229 bool AndroidUsbSocket::GetSSLInfo(net::SSLInfo* ssl_info) {
233 void AndroidUsbSocket::RespondToReaders(bool disconnect) {
234 std::deque<IORequest> read_requests;
235 read_requests.swap(read_requests_);
236 while (!read_requests.empty() && (!read_buffer_.empty() || disconnect)) {
237 IORequest read_request = read_requests.front();
238 read_requests.pop_front();
239 size_t bytes_to_copy =
240 static_cast<size_t>(read_request.length) > read_buffer_.length() ?
241 read_buffer_.length() : static_cast<size_t>(read_request.length);
242 memcpy(read_request.buffer->data(), read_buffer_.data(), bytes_to_copy);
243 if (read_buffer_.length() > bytes_to_copy)
244 read_buffer_ = read_buffer_.substr(bytes_to_copy);
247 read_request.callback.Run(bytes_to_copy);
251 void AndroidUsbSocket::RespondToWriters() {
252 if (!write_requests_.empty()) {
253 IORequest write_request = write_requests_.front();
254 write_requests_.pop_front();
255 write_request.callback.Run(write_request.length);