blob: 5060dbcb4ed9cf7486b91b4e4be9bb4788a94338 [file] [log] [blame]
// Copyright 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#include "android/emulation/AdbHostListener.h"
#include "android/base/async/AsyncSocketServer.h"
#include "android/base/async/ThreadLooper.h"
#include "android/base/Log.h"
#include "android/base/sockets/ScopedSocket.h"
#include "android/base/sockets/SocketUtils.h"
#include "android/emulation/AdbHostServer.h"
#include "android/emulation/AdbTypes.h"
#include <memory>
#include <vector>
namespace android {
namespace emulation {
static bool systemSupportsIPv4() {
int socket = base::socketCreateTcp4();
if (socket < 0 && errno == EAFNOSUPPORT)
return false;
base::socketClose(socket);
return true;
}
using android::base::AsyncSocketServer;
using android::base::ScopedSocket;
bool AdbHostListener::reset(int adbPort) {
if (adbPort < 0) {
mServer.reset();
} else if (!mServer || adbPort != mServer->port()) {
CHECK(adbPort < 65536);
AsyncSocketServer::LoopbackMode mode =
AsyncSocketServer::kIPv4AndOptionalIPv6;
if (!systemSupportsIPv4()) {
mode = AsyncSocketServer::kIPv6;
}
mServer = AsyncSocketServer::createTcpLoopbackServer(
adbPort,
[this](int port) { return this->onHostServerConnection(port); },
mode,
android::base::ThreadLooper::get());
if (!mServer) {
// This can happen when the emulator is probing for a free port
// at startup, so don't print a warning here.
return false;
}
// Don't start listening until startListening() is called.
}
return true;
}
void AdbHostListener::startListening() {
if (mServer) {
mServer->startListening();
}
}
void AdbHostListener::stopListening() {
if (mServer) {
mServer->stopListening();
}
}
void AdbHostListener::notifyServer() {
if (mServer && mAdbClientPort > 0) {
AdbHostServer::notify(mServer->port(), mAdbClientPort);
}
}
bool AdbHostListener::onHostServerConnection(int socket) {
mGuestAgent->onHostConnection(ScopedSocket(socket));
return true;
}
} // namespace emulation
} // namespace android