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
);
123 return 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
);