This source file includes following definitions.
- callback
- is_closed_
- HandleIncoming
- Terminated
- Read
- Write
- SetReceiveBufferSize
- SetSendBufferSize
- Connect
- Disconnect
- IsConnected
- IsConnectedAndIdle
- GetPeerAddress
- GetLocalAddress
- SetSubresourceSpeculation
- SetOmniboxSpeculation
- WasEverUsed
- UsingTCPFastOpen
- WasNpnNegotiated
- GetNegotiatedProtocol
- GetSSLInfo
- RespondToReaders
- RespondToWriters
#include "chrome/browser/devtools/adb/android_usb_socket.h"
#include "base/message_loop/message_loop.h"
namespace {
const int kMaxPayload = 4096;
}
AndroidUsbSocket::IORequest::IORequest(
net::IOBuffer* buffer,
int length,
const net::CompletionCallback& callback)
: buffer(buffer),
length(length),
callback(callback) {
}
AndroidUsbSocket::IORequest::~IORequest() {
}
AndroidUsbSocket::AndroidUsbSocket(scoped_refptr<AndroidUsbDevice> device,
uint32 socket_id,
const std::string& command,
base::Callback<void(uint32)> delete_callback)
: device_(device),
command_(command),
delete_callback_(delete_callback),
local_id_(socket_id),
remote_id_(0),
is_connected_(false),
is_closed_(false) {
}
AndroidUsbSocket::~AndroidUsbSocket() {
DCHECK(CalledOnValidThread());
if (is_connected_)
Disconnect();
delete_callback_.Run(local_id_);
}
void AndroidUsbSocket::HandleIncoming(scoped_refptr<AdbMessage> message) {
CHECK_EQ(message->arg1, local_id_);
switch (message->command) {
case AdbMessage::kCommandOKAY:
if (!is_connected_) {
remote_id_ = message->arg0;
is_connected_ = true;
net::CompletionCallback callback = connect_callback_;
connect_callback_.Reset();
callback.Run(net::OK);
} else {
RespondToWriters();
}
break;
case AdbMessage::kCommandWRTE:
device_->Send(AdbMessage::kCommandOKAY, local_id_, message->arg0, "");
read_buffer_ += message->body;
if (!is_connected_) {
remote_id_ = message->arg0;
is_connected_ = true;
net::CompletionCallback callback = connect_callback_;
connect_callback_.Reset();
callback.Run(net::OK);
} else {
RespondToReaders(false);
}
break;
case AdbMessage::kCommandCLSE:
if (is_connected_)
device_->Send(AdbMessage::kCommandCLSE, local_id_, 0, "");
is_connected_ = false;
is_closed_ = true;
RespondToReaders(true);
break;
default:
break;
}
}
void AndroidUsbSocket::Terminated() {
is_connected_ = false;
is_closed_ = true;
if (!connect_callback_.is_null()) {
net::CompletionCallback callback = connect_callback_;
connect_callback_.Reset();
callback.Run(net::ERR_FAILED);
return;
}
RespondToReaders(true);
}
int AndroidUsbSocket::Read(net::IOBuffer* buffer,
int length,
const net::CompletionCallback& callback) {
if (!is_connected_)
return is_closed_ ? 0 : net::ERR_SOCKET_NOT_CONNECTED;
if (read_buffer_.empty()) {
read_requests_.push_back(IORequest(buffer, length, callback));
return net::ERR_IO_PENDING;
}
size_t bytes_to_copy = static_cast<size_t>(length) > read_buffer_.length() ?
read_buffer_.length() : static_cast<size_t>(length);
memcpy(buffer->data(), read_buffer_.data(), bytes_to_copy);
if (read_buffer_.length() > bytes_to_copy)
read_buffer_ = read_buffer_.substr(bytes_to_copy);
else
read_buffer_ = "";
return bytes_to_copy;
}
int AndroidUsbSocket::Write(net::IOBuffer* buffer,
int length,
const net::CompletionCallback& callback) {
if (!is_connected_)
return net::ERR_SOCKET_NOT_CONNECTED;
if (length > kMaxPayload)
length = kMaxPayload;
write_requests_.push_back(IORequest(NULL, length, callback));
device_->Send(AdbMessage::kCommandWRTE, local_id_, remote_id_,
std::string(buffer->data(), length));
return net::ERR_IO_PENDING;
}
int AndroidUsbSocket::SetReceiveBufferSize(int32 size) {
NOTIMPLEMENTED();
return net::ERR_NOT_IMPLEMENTED;
}
int AndroidUsbSocket::SetSendBufferSize(int32 size) {
NOTIMPLEMENTED();
return net::ERR_NOT_IMPLEMENTED;
}
int AndroidUsbSocket::Connect(const net::CompletionCallback& callback) {
DCHECK(CalledOnValidThread());
if (device_->terminated())
return net::ERR_FAILED;
connect_callback_ = callback;
device_->Send(AdbMessage::kCommandOPEN, local_id_, 0, command_);
return net::ERR_IO_PENDING;
}
void AndroidUsbSocket::Disconnect() {
is_connected_ = false;
device_->Send(AdbMessage::kCommandCLSE, local_id_, remote_id_, "");
RespondToReaders(true);
}
bool AndroidUsbSocket::IsConnected() const {
DCHECK(CalledOnValidThread());
return is_connected_;
}
bool AndroidUsbSocket::IsConnectedAndIdle() const {
NOTIMPLEMENTED();
return false;
}
int AndroidUsbSocket::GetPeerAddress(net::IPEndPoint* address) const {
net::IPAddressNumber ip(net::kIPv4AddressSize);
*address = net::IPEndPoint(ip, 0);
return net::OK;
}
int AndroidUsbSocket::GetLocalAddress(net::IPEndPoint* address) const {
NOTIMPLEMENTED();
return net::ERR_NOT_IMPLEMENTED;
}
const net::BoundNetLog& AndroidUsbSocket::NetLog() const {
return net_log_;
}
void AndroidUsbSocket::SetSubresourceSpeculation() {
NOTIMPLEMENTED();
}
void AndroidUsbSocket::SetOmniboxSpeculation() {
NOTIMPLEMENTED();
}
bool AndroidUsbSocket::WasEverUsed() const {
NOTIMPLEMENTED();
return true;
}
bool AndroidUsbSocket::UsingTCPFastOpen() const {
NOTIMPLEMENTED();
return true;
}
bool AndroidUsbSocket::WasNpnNegotiated() const {
NOTIMPLEMENTED();
return true;
}
net::NextProto AndroidUsbSocket::GetNegotiatedProtocol() const {
NOTIMPLEMENTED();
return net::kProtoUnknown;
}
bool AndroidUsbSocket::GetSSLInfo(net::SSLInfo* ssl_info) {
return false;
}
void AndroidUsbSocket::RespondToReaders(bool disconnect) {
std::deque<IORequest> read_requests;
read_requests.swap(read_requests_);
while (!read_requests.empty() && (!read_buffer_.empty() || disconnect)) {
IORequest read_request = read_requests.front();
read_requests.pop_front();
size_t bytes_to_copy =
static_cast<size_t>(read_request.length) > read_buffer_.length() ?
read_buffer_.length() : static_cast<size_t>(read_request.length);
memcpy(read_request.buffer->data(), read_buffer_.data(), bytes_to_copy);
if (read_buffer_.length() > bytes_to_copy)
read_buffer_ = read_buffer_.substr(bytes_to_copy);
else
read_buffer_ = "";
read_request.callback.Run(bytes_to_copy);
}
}
void AndroidUsbSocket::RespondToWriters() {
if (!write_requests_.empty()) {
IORequest write_request = write_requests_.front();
write_requests_.pop_front();
write_request.callback.Run(write_request.length);
}
}