Loading libs/binder/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -501,6 +501,7 @@ cc_library { "libbase", "libbinder", "libbinder_ndk", "libcutils_sockets", "liblog", "libutils", ], Loading libs/binder/RpcServer.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -564,6 +564,29 @@ status_t RpcServer::setupSocketServer(const RpcSocketAddress& addr) { return OK; } status_t RpcServer::setupRawSocketServer(base::unique_fd socket_fd) { RpcTransportFd transportFd(std::move(socket_fd)); if (!transportFd.fd.ok()) { int savedErrno = errno; ALOGE("Could not get initialized Unix socket: %s", strerror(savedErrno)); return -savedErrno; } // Right now, we create all threads at once, making accept4 slow. To avoid hanging the client, // the backlog is increased to a large number. // TODO(b/189955605): Once we create threads dynamically & lazily, the backlog can be reduced // to 1. if (0 != TEMP_FAILURE_RETRY(listen(transportFd.fd.get(), 50 /*backlog*/))) { int savedErrno = errno; ALOGE("Could not listen initialized Unix socket: %s", strerror(savedErrno)); return -savedErrno; } if (status_t status = setupExternalServer(std::move(transportFd.fd)); status != OK) { ALOGE("Another thread has set up server while calling setupSocketServer. Race?"); return status; } return OK; } void RpcServer::onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) { const std::vector<uint8_t>& id = session->mId; LOG_ALWAYS_FATAL_IF(id.empty(), "Server sessions must be initialized with ID"); Loading libs/binder/include/binder/RpcServer.h +10 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,16 @@ public: */ [[nodiscard]] status_t setupUnixDomainServer(const char* path); /** * Sets up an RPC server with a raw socket file descriptor. * The socket should be created and bound to a socket address already, e.g. * the socket can be created in init.rc. * * This method is used in the libbinder_rpc_unstable API * RunInitUnixDomainRpcServer(). */ [[nodiscard]] status_t setupRawSocketServer(base::unique_fd socket_fd); /** * Creates an RPC server at the current port. */ Loading libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp +14 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,20 @@ bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* c AIBinder* VsockRpcClient(unsigned int cid, unsigned int port); // Starts a Unix domain RPC server with a given init-managed Unix domain `name` and // a given root IBinder object. // The socket should be created in init.rc with the same `name`. // // This function sets up the server, calls readyCallback with a given param, and // then joins before returning. bool RunInitUnixDomainRpcServer(AIBinder* service, const char* name, void (*readyCallback)(void* param), void* param); // Gets the service via the RPC binder with Unix domain socket with the given // Unix socket `name`. // The final Unix domain socket path name is /dev/socket/`name`. AIBinder* UnixDomainRpcClient(const char* name); // Connect to an RPC server with preconnected file descriptors. // // requestFd should connect to the server and return a valid file descriptor, or Loading libs/binder/libbinder_rpc_unstable.cpp +38 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android/binder_libbinder.h> #include <binder/RpcServer.h> #include <binder/RpcSession.h> #include <cutils/sockets.h> #include <linux/vm_sockets.h> using android::OK; Loading @@ -30,6 +31,17 @@ using android::base::unique_fd; extern "C" { void RunRpcServer(android::sp<RpcServer>& server, AIBinder* service, void (*readyCallback)(void* param), void* param) { server->setRootObject(AIBinder_toPlatformBinder(service)); if (readyCallback) readyCallback(param); server->join(); // Shutdown any open sessions since server failed. (void)server->shutdown(); } bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context), void* factoryContext, unsigned int port) { auto server = RpcServer::make(); Loading Loading @@ -60,13 +72,7 @@ bool RunVsockRpcServerCallback(AIBinder* service, unsigned int port, << " error: " << statusToString(status).c_str(); return false; } server->setRootObject(AIBinder_toPlatformBinder(service)); if (readyCallback) readyCallback(param); server->join(); // Shutdown any open sessions since server failed. (void)server->shutdown(); RunRpcServer(server, service, readyCallback, param); return true; } Loading @@ -84,6 +90,31 @@ AIBinder* VsockRpcClient(unsigned int cid, unsigned int port) { return AIBinder_fromPlatformBinder(session->getRootObject()); } bool RunInitUnixDomainRpcServer(AIBinder* service, const char* name, void (*readyCallback)(void* param), void* param) { auto server = RpcServer::make(); auto fd = unique_fd(android_get_control_socket(name)); if (status_t status = server->setupRawSocketServer(std::move(fd)); status != OK) { LOG(ERROR) << "Failed to set up Unix Domain RPC server with name " << name << " error: " << statusToString(status).c_str(); return false; } RunRpcServer(server, service, readyCallback, param); return true; } AIBinder* UnixDomainRpcClient(const char* name) { std::string pathname(name); pathname = ANDROID_SOCKET_DIR "/" + pathname; auto session = RpcSession::make(); if (status_t status = session->setupUnixDomainClient(pathname.c_str()); status != OK) { LOG(ERROR) << "Failed to set up Unix Domain RPC client with path: " << pathname << " error: " << statusToString(status).c_str(); return nullptr; } return AIBinder_fromPlatformBinder(session->getRootObject()); } AIBinder* RpcPreconnectedClient(int (*requestFd)(void* param), void* param) { auto session = RpcSession::make(); auto request = [=] { return unique_fd{requestFd(param)}; }; Loading Loading
libs/binder/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -501,6 +501,7 @@ cc_library { "libbase", "libbinder", "libbinder_ndk", "libcutils_sockets", "liblog", "libutils", ], Loading
libs/binder/RpcServer.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -564,6 +564,29 @@ status_t RpcServer::setupSocketServer(const RpcSocketAddress& addr) { return OK; } status_t RpcServer::setupRawSocketServer(base::unique_fd socket_fd) { RpcTransportFd transportFd(std::move(socket_fd)); if (!transportFd.fd.ok()) { int savedErrno = errno; ALOGE("Could not get initialized Unix socket: %s", strerror(savedErrno)); return -savedErrno; } // Right now, we create all threads at once, making accept4 slow. To avoid hanging the client, // the backlog is increased to a large number. // TODO(b/189955605): Once we create threads dynamically & lazily, the backlog can be reduced // to 1. if (0 != TEMP_FAILURE_RETRY(listen(transportFd.fd.get(), 50 /*backlog*/))) { int savedErrno = errno; ALOGE("Could not listen initialized Unix socket: %s", strerror(savedErrno)); return -savedErrno; } if (status_t status = setupExternalServer(std::move(transportFd.fd)); status != OK) { ALOGE("Another thread has set up server while calling setupSocketServer. Race?"); return status; } return OK; } void RpcServer::onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) { const std::vector<uint8_t>& id = session->mId; LOG_ALWAYS_FATAL_IF(id.empty(), "Server sessions must be initialized with ID"); Loading
libs/binder/include/binder/RpcServer.h +10 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,16 @@ public: */ [[nodiscard]] status_t setupUnixDomainServer(const char* path); /** * Sets up an RPC server with a raw socket file descriptor. * The socket should be created and bound to a socket address already, e.g. * the socket can be created in init.rc. * * This method is used in the libbinder_rpc_unstable API * RunInitUnixDomainRpcServer(). */ [[nodiscard]] status_t setupRawSocketServer(base::unique_fd socket_fd); /** * Creates an RPC server at the current port. */ Loading
libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp +14 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,20 @@ bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* c AIBinder* VsockRpcClient(unsigned int cid, unsigned int port); // Starts a Unix domain RPC server with a given init-managed Unix domain `name` and // a given root IBinder object. // The socket should be created in init.rc with the same `name`. // // This function sets up the server, calls readyCallback with a given param, and // then joins before returning. bool RunInitUnixDomainRpcServer(AIBinder* service, const char* name, void (*readyCallback)(void* param), void* param); // Gets the service via the RPC binder with Unix domain socket with the given // Unix socket `name`. // The final Unix domain socket path name is /dev/socket/`name`. AIBinder* UnixDomainRpcClient(const char* name); // Connect to an RPC server with preconnected file descriptors. // // requestFd should connect to the server and return a valid file descriptor, or Loading
libs/binder/libbinder_rpc_unstable.cpp +38 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android/binder_libbinder.h> #include <binder/RpcServer.h> #include <binder/RpcSession.h> #include <cutils/sockets.h> #include <linux/vm_sockets.h> using android::OK; Loading @@ -30,6 +31,17 @@ using android::base::unique_fd; extern "C" { void RunRpcServer(android::sp<RpcServer>& server, AIBinder* service, void (*readyCallback)(void* param), void* param) { server->setRootObject(AIBinder_toPlatformBinder(service)); if (readyCallback) readyCallback(param); server->join(); // Shutdown any open sessions since server failed. (void)server->shutdown(); } bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context), void* factoryContext, unsigned int port) { auto server = RpcServer::make(); Loading Loading @@ -60,13 +72,7 @@ bool RunVsockRpcServerCallback(AIBinder* service, unsigned int port, << " error: " << statusToString(status).c_str(); return false; } server->setRootObject(AIBinder_toPlatformBinder(service)); if (readyCallback) readyCallback(param); server->join(); // Shutdown any open sessions since server failed. (void)server->shutdown(); RunRpcServer(server, service, readyCallback, param); return true; } Loading @@ -84,6 +90,31 @@ AIBinder* VsockRpcClient(unsigned int cid, unsigned int port) { return AIBinder_fromPlatformBinder(session->getRootObject()); } bool RunInitUnixDomainRpcServer(AIBinder* service, const char* name, void (*readyCallback)(void* param), void* param) { auto server = RpcServer::make(); auto fd = unique_fd(android_get_control_socket(name)); if (status_t status = server->setupRawSocketServer(std::move(fd)); status != OK) { LOG(ERROR) << "Failed to set up Unix Domain RPC server with name " << name << " error: " << statusToString(status).c_str(); return false; } RunRpcServer(server, service, readyCallback, param); return true; } AIBinder* UnixDomainRpcClient(const char* name) { std::string pathname(name); pathname = ANDROID_SOCKET_DIR "/" + pathname; auto session = RpcSession::make(); if (status_t status = session->setupUnixDomainClient(pathname.c_str()); status != OK) { LOG(ERROR) << "Failed to set up Unix Domain RPC client with path: " << pathname << " error: " << statusToString(status).c_str(); return nullptr; } return AIBinder_fromPlatformBinder(session->getRootObject()); } AIBinder* RpcPreconnectedClient(int (*requestFd)(void* param), void* param) { auto session = RpcSession::make(); auto request = [=] { return unique_fd{requestFd(param)}; }; Loading