Move jdwp connection abstraction from ART apex to adbd apex.
Test: ./art/tools/run-jdwp-tests.sh
Change-Id: I3114b8403f3548700a45df5d7bb72ebe727adec1
diff --git a/adbconnection/adbconnection.cc b/adbconnection/adbconnection.cc
index 0824eb4..2234ce4 100644
--- a/adbconnection/adbconnection.cc
+++ b/adbconnection/adbconnection.cc
@@ -15,16 +15,17 @@
*/
#include <array>
+#include <iterator>
#include "adbconnection.h"
+#include "adbconnection/client.h"
#include "android-base/endian.h"
#include "android-base/stringprintf.h"
#include "base/file_utils.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/mutex.h"
-#include "base/socket_peer_is_trusted.h"
#include "jni/java_vm_ext.h"
#include "jni/jni_env_ext.h"
#include "mirror/throwable.h"
@@ -66,7 +67,6 @@
static constexpr int kEventfdLocked = 0;
static constexpr int kEventfdUnlocked = 1;
-static constexpr int kControlSockSendTimeout = 10;
static constexpr size_t kPacketHeaderLen = 11;
static constexpr off_t kPacketSizeOff = 0;
@@ -125,7 +125,7 @@
controller_(this),
ddm_callback_(this),
sleep_event_fd_(-1),
- control_sock_(-1),
+ control_ctx_(nullptr, adbconnection_client_destroy),
local_agent_control_sock_(-1),
remote_agent_control_sock_(-1),
adb_connection_socket_(-1),
@@ -447,57 +447,18 @@
}
android::base::unique_fd AdbConnectionState::ReadFdFromAdb() {
- // We don't actually care about the data that is sent. We do need to receive something though.
- char dummy = '!';
- union {
- cmsghdr cm;
- char buffer[CMSG_SPACE(sizeof(int))];
- } cm_un;
-
- iovec iov;
- iov.iov_base = &dummy;
- iov.iov_len = 1;
-
- msghdr msg;
- msg.msg_name = nullptr;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
- msg.msg_control = cm_un.buffer;
- msg.msg_controllen = sizeof(cm_un.buffer);
-
- cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_len = msg.msg_controllen;
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- (reinterpret_cast<int*>(CMSG_DATA(cmsg)))[0] = -1;
-
- int rc = TEMP_FAILURE_RETRY(recvmsg(control_sock_, &msg, 0));
-
- if (rc <= 0) {
- return android::base::unique_fd(-1);
- } else {
- VLOG(jdwp) << "Fds have been received from ADB!";
- }
-
- return android::base::unique_fd((reinterpret_cast<int*>(CMSG_DATA(cmsg)))[0]);
+ return android::base::unique_fd(adbconnection_client_receive_jdwp_fd(control_ctx_.get()));
}
bool AdbConnectionState::SetupAdbConnection() {
- int sleep_ms = 500;
- const int sleep_max_ms = 2*1000;
+ int sleep_ms = 500;
+ const int sleep_max_ms = 2 * 1000;
- android::base::unique_fd sock(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0));
- if (sock < 0) {
- PLOG(ERROR) << "Could not create ADB control socket";
- return false;
- }
- struct timeval timeout;
- timeout.tv_sec = kControlSockSendTimeout;
- timeout.tv_usec = 0;
- setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
- int32_t pid = getpid();
+ const AdbConnectionClientInfo infos[] = {
+ {.type = AdbConnectionClientInfoType::pid, .data.pid = static_cast<uint64_t>(getpid())},
+ {.type = AdbConnectionClientInfoType::debuggable, .data.debuggable = true},
+ };
+ const AdbConnectionClientInfo* info_ptrs[] = {&infos[0], &infos[1]};
while (!shutting_down_) {
// If adbd isn't running, because USB debugging was disabled or
@@ -511,39 +472,20 @@
// of battery life, we should consider timing out and giving
// up after a few minutes in case somebody ships an app with
// the debuggable flag set.
- int ret = connect(sock, &control_addr_.controlAddrPlain, control_addr_len_);
- if (ret == 0) {
- bool trusted = sock >= 0 && art::SocketPeerIsTrusted(sock);
- if (!trusted) {
- LOG(ERROR) << "adb socket is not trusted. Aborting connection.";
- if (sock >= 0 && shutdown(sock, SHUT_RDWR)) {
- PLOG(ERROR) << "trouble shutting down socket";
- }
- return false;
- }
- /* now try to send our pid to the ADB daemon */
- ret = TEMP_FAILURE_RETRY(send(sock, &pid, sizeof(pid), 0));
- if (ret == sizeof(pid)) {
- VLOG(jdwp) << "PID " << pid << " sent to adb";
- control_sock_ = std::move(sock);
- return true;
- } else {
- PLOG(ERROR) << "Weird, can't send JDWP process pid to ADB. Aborting connection.";
- return false;
- }
- } else {
- if (VLOG_IS_ON(jdwp)) {
- PLOG(ERROR) << "Can't connect to ADB control socket. Will retry.";
- }
+ control_ctx_.reset(adbconnection_client_new(info_ptrs, std::size(infos)));
+ if (control_ctx_) {
+ return true;
+ }
- usleep(sleep_ms * 1000);
+ // We failed to connect.
+ usleep(sleep_ms * 1000);
- sleep_ms += (sleep_ms >> 1);
- if (sleep_ms > sleep_max_ms) {
- sleep_ms = sleep_max_ms;
- }
+ sleep_ms += (sleep_ms >> 1);
+ if (sleep_ms > sleep_max_ms) {
+ sleep_ms = sleep_max_ms;
}
}
+
return false;
}
@@ -554,12 +496,12 @@
self->SetState(art::kWaitingInMainDebuggerLoop);
// shutting_down_ set by StopDebuggerThreads
while (!shutting_down_) {
- // First get the control_sock_ from adb if we don't have one. We only need to do this once.
- if (control_sock_ == -1 && !SetupAdbConnection()) {
+ // First, connect to adbd if we haven't already.
+ if (!control_ctx_ && !SetupAdbConnection()) {
LOG(ERROR) << "Failed to setup adb connection.";
return;
}
- while (!shutting_down_ && control_sock_ != -1) {
+ while (!shutting_down_ && control_ctx_) {
bool should_listen_on_connection = !agent_has_socket_ && !sent_agent_fds_;
struct pollfd pollfds[4] = {
{ sleep_event_fd_, POLLIN, 0 },
@@ -567,7 +509,8 @@
{ (agent_loaded_ ? local_agent_control_sock_ : -1), POLLIN, 0 },
// Check for the control_sock_ actually going away. Only do this if we don't have an active
// connection.
- { (adb_connection_socket_ == -1 ? control_sock_ : -1), POLLIN | POLLRDHUP, 0 },
+ { (adb_connection_socket_ == -1 ? adbconnection_client_pollfd(control_ctx_.get()) : -1),
+ POLLIN | POLLRDHUP, 0 },
// if we have not loaded the agent either the adb_connection_socket_ is -1 meaning we don't
// have a real connection yet or the socket through adb needs to be listened to for incoming
// data that the agent or this plugin can handle.
@@ -617,10 +560,10 @@
{
// Hold onto this lock so that concurrent ddm publishes don't try to use an illegal fd.
ScopedEventFdLock sefdl(adb_write_event_fd_);
- android::base::unique_fd new_fd(ReadFdFromAdb());
+ android::base::unique_fd new_fd(adbconnection_client_receive_jdwp_fd(control_ctx_.get()));
if (new_fd == -1) {
// Something went wrong. We need to retry getting the control socket.
- control_sock_.reset();
+ control_ctx_.reset();
break;
} else if (adb_connection_socket_ != -1) {
// We already have a connection.
@@ -645,7 +588,7 @@
// Reset the connection since we don't have an active socket through the adb server.
DCHECK(!agent_has_socket_) << "We shouldn't be doing anything if there is already a "
<< "connection active";
- control_sock_.reset();
+ control_ctx_.reset();
break;
} else if (FlagsSet(adb_socket_poll.revents, POLLIN)) {
DCHECK(!agent_has_socket_);