Adding Android Binder Bridge (abb) utility launched from adbd.
Once launched, abb will listen for incoming Binder cli requests.
Executing in-process provides 6x latency improvement (125ms vs 25ms on
PixelXL) for commands like 'package path'
Intended usage by Android Studio for fast deployment and patching of APKs.
Test: manual
BUG: 111621042
Change-Id: Ica84eb2ec9628efa441ecd627b119f3361feaf9f
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index e6fefda..605d27d 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -20,6 +20,11 @@
#include <unistd.h>
+#if !ADB_HOST
+#include <sys/socket.h>
+#include <sys/un.h>
+#endif
+
#include <thread>
#include <android-base/stringprintf.h>
@@ -182,3 +187,79 @@
return false;
}
}
+
+#if defined(__linux__)
+bool SendFileDescriptor(int socket_fd, int fd) {
+ struct msghdr msg;
+ struct iovec iov;
+ char dummy = '!';
+ union {
+ cmsghdr cm;
+ char buffer[CMSG_SPACE(sizeof(int))];
+ } cm_un;
+
+ iov.iov_base = &dummy;
+ iov.iov_len = 1;
+ 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 = CMSG_LEN(sizeof(int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ ((int*)CMSG_DATA(cmsg))[0] = fd;
+
+ int ret = TEMP_FAILURE_RETRY(sendmsg(socket_fd, &msg, 0));
+ if (ret < 0) {
+ D("sending file descriptor via socket %d failed: %s", socket_fd, strerror(errno));
+ return false;
+ }
+
+ D("sent file descriptor %d to via socket %d", fd, socket_fd);
+ return true;
+}
+
+bool ReceiveFileDescriptor(int socket_fd, unique_fd* fd, std::string* error) {
+ 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 = CMSG_LEN(sizeof(int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ ((int*)(CMSG_DATA(cmsg)))[0] = -1;
+
+ int rc = TEMP_FAILURE_RETRY(recvmsg(socket_fd, &msg, 0));
+ if (rc <= 0) {
+ *error = perror_str("receiving file descriptor via socket failed");
+ D("receiving file descriptor via socket %d failed: %s", socket_fd, strerror(errno));
+ return false;
+ }
+
+ fd->reset(((int*)(CMSG_DATA(cmsg)))[0]);
+ D("received file descriptor %d to via socket %d", fd->get(), socket_fd);
+
+ return true;
+}
+#endif