adbd: move jdwp listening logic into ART.
Test: manually use jdwp
Change-Id: Ia09a5c643cba9ec5f343c9767d43d72b077bc247
diff --git a/Android.bp b/Android.bp
index 114eb2a..b6aff3e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -344,6 +344,7 @@
generated_headers: ["platform_tools_version"],
static_libs: [
+ "libadbconnection_server",
"libdiagnose_usb",
],
@@ -395,6 +396,7 @@
],
static_libs: [
+ "libadbconnection_server",
"libadbd_core",
"libdiagnose_usb",
],
@@ -531,6 +533,7 @@
},
static_libs: [
+ "libadbconnection_server",
"libadbd",
"libadbd_services",
"libasyncio",
diff --git a/daemon/include/adbd/usb.h b/daemon/include/adbd/usb.h
index fca3c58..2204246 100644
--- a/daemon/include/adbd/usb.h
+++ b/daemon/include/adbd/usb.h
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+#include <linux/usb/functionfs.h>
+
#include <atomic>
#include <condition_variable>
#include <mutex>
diff --git a/daemon/jdwp_service.cpp b/daemon/jdwp_service.cpp
index cd9b669..b92a7de 100644
--- a/daemon/jdwp_service.cpp
+++ b/daemon/jdwp_service.cpp
@@ -30,15 +30,21 @@
#include <list>
#include <memory>
+#include <thread>
#include <vector>
+#include <adbconnection/server.h>
#include <android-base/cmsg.h>
+#include <android-base/unique_fd.h>
#include "adb.h"
#include "adb_io.h"
#include "adb_unique_fd.h"
#include "adb_utils.h"
+using android::base::borrowed_fd;
+using android::base::unique_fd;
+
/* here's how these things work.
when adbd starts, it creates a unix server socket
@@ -133,16 +139,16 @@
static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>();
struct JdwpProcess {
- explicit JdwpProcess(int socket) {
+ JdwpProcess(unique_fd socket, pid_t pid) {
+ CHECK(pid != 0);
+
this->socket = socket;
- this->fde = fdevent_create(socket, jdwp_process_event, this);
+ this->pid = pid;
+ this->fde = fdevent_create(socket.release(), jdwp_process_event, this);
if (!this->fde) {
LOG(FATAL) << "could not create fdevent for new JDWP process";
}
-
- /* start by waiting for the PID */
- fdevent_add(this->fde, FDE_READ);
}
~JdwpProcess() {
@@ -160,18 +166,12 @@
}
void RemoveFromList() {
- if (this->pid >= 0) {
- D("removing pid %d from jdwp process list", this->pid);
- } else {
- D("removing transient JdwpProcess from list");
- }
-
auto pred = [this](const auto& proc) { return proc.get() == this; };
_jdwp_list.remove_if(pred);
}
+ borrowed_fd socket = -1;
int32_t pid = -1;
- int socket = -1;
fdevent* fde = nullptr;
std::vector<unique_fd> out_fds;
@@ -181,11 +181,6 @@
std::string temp;
for (auto& proc : _jdwp_list) {
- /* skip transient connections */
- if (proc->pid < 0) {
- continue;
- }
-
std::string next = std::to_string(proc->pid) + "\n";
if (temp.length() + next.length() > bufferlen) {
D("truncating JDWP process list (max len = %zu)", bufferlen);
@@ -214,24 +209,12 @@
static void jdwp_process_event(int socket, unsigned events, void* _proc) {
JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc);
- CHECK_EQ(socket, proc->socket);
+ CHECK_EQ(socket, proc->socket.get());
if (events & FDE_READ) {
- if (proc->pid < 0) {
- ssize_t rc = TEMP_FAILURE_RETRY(recv(socket, &proc->pid, sizeof(proc->pid), 0));
- if (rc != sizeof(proc->pid)) {
- D("failed to read jdwp pid: rc = %zd, errno = %s", rc, strerror(errno));
- goto CloseProcess;
- }
-
- /* all is well, keep reading to detect connection closure */
- D("Adding pid %d to jdwp process list", proc->pid);
- jdwp_process_list_updated();
- } else {
- // We already have the PID, if we can read from the socket, we've probably hit EOF.
- D("terminating JDWP connection %d", proc->pid);
- goto CloseProcess;
- }
+ // We already have the PID, if we can read from the socket, we've probably hit EOF.
+ D("terminating JDWP connection %d", proc->pid);
+ goto CloseProcess;
}
if (events & FDE_WRITE) {
@@ -284,98 +267,6 @@
return unique_fd{};
}
-/** VM DEBUG CONTROL SOCKET
- **
- ** we do implement a custom asocket to receive the data
- **/
-
-/* name of the debug control Unix socket */
-#define JDWP_CONTROL_NAME "\0jdwp-control"
-#define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME) - 1)
-
-struct JdwpControl {
- int listen_socket;
- fdevent* fde;
-};
-
-static JdwpControl _jdwp_control;
-
-static void jdwp_control_event(int s, unsigned events, void* user);
-
-static int jdwp_control_init(JdwpControl* control, const char* sockname, int socknamelen) {
- sockaddr_un addr;
- socklen_t addrlen;
- int maxpath = sizeof(addr.sun_path);
- int pathlen = socknamelen;
-
- if (pathlen >= maxpath) {
- D("vm debug control socket name too long (%d extra chars)", pathlen + 1 - maxpath);
- return -1;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, sockname, socknamelen);
-
- unique_fd s(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0));
- if (s < 0) {
- D("could not create vm debug control socket. %d: %s", errno, strerror(errno));
- return -1;
- }
-
- addrlen = pathlen + sizeof(addr.sun_family);
-
- if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
- D("could not bind vm debug control socket: %d: %s", errno, strerror(errno));
- return -1;
- }
-
- if (listen(s.get(), 4) < 0) {
- D("listen failed in jdwp control socket: %d: %s", errno, strerror(errno));
- return -1;
- }
-
- control->listen_socket = s.release();
- control->fde = fdevent_create(control->listen_socket, jdwp_control_event, control);
- if (control->fde == nullptr) {
- D("could not create fdevent for jdwp control socket");
- return -1;
- }
-
- /* only wait for incoming connections */
- fdevent_add(control->fde, FDE_READ);
-
- D("jdwp control socket started (%d)", control->listen_socket);
- return 0;
-}
-
-static void jdwp_control_event(int fd, unsigned events, void* _control) {
- JdwpControl* control = (JdwpControl*)_control;
-
- CHECK_EQ(fd, control->listen_socket);
- if (events & FDE_READ) {
- int s = adb_socket_accept(control->listen_socket, nullptr, nullptr);
- if (s < 0) {
- if (errno == ECONNABORTED) {
- /* oops, the JDWP process died really quick */
- D("oops, the JDWP process died really quick");
- return;
- } else {
- /* the socket is probably closed ? */
- D("weird accept() failed on jdwp control socket: %s", strerror(errno));
- return;
- }
- }
-
- auto proc = std::make_unique<JdwpProcess>(s);
- if (!proc) {
- LOG(FATAL) << "failed to allocate JdwpProcess";
- }
-
- _jdwp_list.emplace_back(std::move(proc));
- }
-}
-
/** "jdwp" local service implementation
** this simply returns the list of known JDWP process pids
**/
@@ -526,7 +417,22 @@
}
int init_jdwp(void) {
- return jdwp_control_init(&_jdwp_control, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN);
+ std::thread([]() {
+ adb_thread_setname("jdwp control");
+ adbconnection_listen([](int fd, pid_t pid) {
+ LOG(INFO) << "jdwp connection from " << pid;
+ fdevent_run_on_main_thread([fd, pid] {
+ unique_fd ufd(fd);
+ auto proc = std::make_unique<JdwpProcess>(std::move(ufd), pid);
+ if (!proc) {
+ LOG(FATAL) << "failed to allocate JdwpProcess";
+ }
+ _jdwp_list.emplace_back(std::move(proc));
+ jdwp_process_list_updated();
+ });
+ });
+ }).detach();
+ return 0;
}
#endif /* !ADB_HOST */