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_);