Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 091050a3 authored by Inseob Kim's avatar Inseob Kim
Browse files

Add rpc server using service factory

Using the service factory, users can put contexts to binder services.
For example, the server can identify calling clients.

Bug: 199259751
Test: atest MicrodroidHostTestCases ComposHostTestCases
Change-Id: I8ed845e2a8e49a61531e6e4aadc88de7146fe8c0
parent 828b2acb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -331,6 +331,7 @@ cc_library {
        "libbase",
        "libbinder",
        "libbinder_ndk",
        "liblog",
        "libutils",
    ],
    export_include_dirs: ["include_rpc_unstable"],
+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

#pragma once

#include <sys/socket.h>

extern "C" {

struct AIBinder;
@@ -30,6 +32,12 @@ bool RunRpcServer(AIBinder* service, unsigned int port);
bool RunRpcServerCallback(AIBinder* service, unsigned int port, void (*readyCallback)(void* param),
                          void* param);

// Starts an RPC server on a given port and a given root IBinder object.
// This function sets up the server, calls readyCallback with a given param, and
// then joins before returning.
bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
                          void* factoryContext, unsigned int port);

AIBinder* RpcClient(unsigned int cid, unsigned int port);

// Connect to an RPC server with preconnected file descriptors.
+23 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <android/binder_libbinder.h>
#include <binder/RpcServer.h>
#include <binder/RpcSession.h>
#include <linux/vm_sockets.h>

using android::OK;
using android::RpcServer;
@@ -29,6 +30,28 @@ using android::base::unique_fd;

extern "C" {

bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
                             void* factoryContext, unsigned int port) {
    auto server = RpcServer::make();
    if (status_t status = server->setupVsockServer(port); status != OK) {
        LOG(ERROR) << "Failed to set up vsock server with port " << port
                   << " error: " << statusToString(status).c_str();
        return false;
    }
    server->setPerSessionRootObject([=](const sockaddr* addr, socklen_t addrlen) {
        LOG_ALWAYS_FATAL_IF(addr->sa_family != AF_VSOCK, "address is not a vsock");
        LOG_ALWAYS_FATAL_IF(addrlen < sizeof(sockaddr_vm), "sockaddr is truncated");
        const sockaddr_vm* vaddr = reinterpret_cast<const sockaddr_vm*>(addr);
        return AIBinder_toPlatformBinder(factory(vaddr->svm_cid, factoryContext));
    });

    server->join();

    // Shutdown any open sessions since server failed.
    (void)server->shutdown();
    return true;
}

bool RunRpcServerCallback(AIBinder* service, unsigned int port, void (*readyCallback)(void* param),
                          void* param) {
    auto server = RpcServer::make();