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

Commit 8931ca6b authored by Yiming Jing's avatar Yiming Jing Committed by Automerger Merge Worker
Browse files

Merge "rpc_binder: Create C/Rust bindings for inet socket" am: 968b998a am: 279ec407

parents 4c814659 279ec407
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -57,6 +57,15 @@ enum class ARpcSession_FileDescriptorTransportMode {
// could not be started.
[[nodiscard]] ARpcServer* ARpcServer_newUnixDomainBootstrap(AIBinder* service, int bootstrapFd);

// Starts an RPC server on a given IP address+port and a given IBinder object.
// Returns an opaque handle to the running server instance, or null if the server
// could not be started.
// Does not take ownership of `service`.
// Returns an opaque handle to the running service instance, or null if the server
// could not be started.
[[nodiscard]] ARpcServer* ARpcServer_newInet(AIBinder* service, const char* address,
                                             unsigned int port);

// Sets the list of supported file descriptor transport modes of this RPC server.
void ARpcServer_setSupportedFileDescriptorTransportModes(
        ARpcServer* handle,
@@ -98,6 +107,10 @@ AIBinder* ARpcSession_setupUnixDomainClient(ARpcSession* session, const char* na
AIBinder* ARpcSession_setupUnixDomainBootstrapClient(ARpcSession* session,
                                                     int bootstrapFd);

// Connects to an RPC server over an INET socket at a given IP address on a given port.
// Returns the root Binder object of the server.
AIBinder* ARpcSession_setupInet(ARpcSession* session, const char* address, unsigned int port);

// Connects to an RPC server with preconnected file descriptors.
//
// requestFd should connect to the server and return a valid file descriptor, or
+21 −0
Original line number Diff line number Diff line
@@ -145,6 +145,17 @@ ARpcServer* ARpcServer_newUnixDomainBootstrap(AIBinder* service, int bootstrapFd
    return createObjectHandle<ARpcServer>(server);
}

ARpcServer* ARpcServer_newInet(AIBinder* service, const char* address, unsigned int port) {
    auto server = RpcServer::make();
    if (status_t status = server->setupInetServer(address, port, nullptr); status != OK) {
        LOG(ERROR) << "Failed to set up inet RPC server with address " << address << " and port "
                   << port << " error: " << statusToString(status).c_str();
        return nullptr;
    }
    server->setRootObject(AIBinder_toPlatformBinder(service));
    return createObjectHandle<ARpcServer>(server);
}

void ARpcServer_setSupportedFileDescriptorTransportModes(
        ARpcServer* handle, const ARpcSession_FileDescriptorTransportMode modes[],
        size_t modes_len) {
@@ -222,6 +233,16 @@ AIBinder* ARpcSession_setupUnixDomainBootstrapClient(ARpcSession* handle, int bo
    return AIBinder_fromPlatformBinder(session->getRootObject());
}

AIBinder* ARpcSession_setupInet(ARpcSession* handle, const char* address, unsigned int port) {
    auto session = handleToStrongPointer<RpcSession>(handle);
    if (status_t status = session->setupInetClient(address, port); status != OK) {
        LOG(ERROR) << "Failed to set up inet RPC client with address " << address << " and port "
                   << port << " error: " << statusToString(status).c_str();
        return nullptr;
    }
    return AIBinder_fromPlatformBinder(session->getRootObject());
}

AIBinder* ARpcSession_setupPreconnectedClient(ARpcSession* handle, int (*requestFd)(void* param),
                                              void* param) {
    auto session = handleToStrongPointer<RpcSession>(handle);
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ LIBBINDER_RPC_UNSTABLE_SHIM { # platform-only
  global:
    ARpcServer_free;
    ARpcServer_join;
    ARpcServer_newInet;
    ARpcServer_newInitUnixDomain;
    ARpcServer_newVsock;
    ARpcServer_shutdown;
+23 −0
Original line number Diff line number Diff line
@@ -102,6 +102,29 @@ impl RpcServer {
        }
    }

    /// Creates a binder RPC server, serving the supplied binder service implementation on the given
    /// IP address and port.
    pub fn new_inet(mut service: SpIBinder, address: &str, port: u32) -> Result<RpcServer, Error> {
        let address = match CString::new(address) {
            Ok(s) => s,
            Err(e) => {
                log::error!("Cannot convert {} to CString. Error: {:?}", address, e);
                return Err(Error::from(ErrorKind::InvalidInput));
            }
        };
        let service = service.as_native_mut();

        // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
        // Plus the binder objects are threadsafe.
        unsafe {
            Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newInet(
                service,
                address.as_ptr(),
                port,
            ))
        }
    }

    unsafe fn checked_from_ptr(ptr: *mut ARpcServer) -> Result<RpcServer, Error> {
        if ptr.is_null() {
            return Err(Error::new(ErrorKind::Other, "Failed to start server"));
+26 −0
Original line number Diff line number Diff line
@@ -144,6 +144,32 @@ impl RpcSessionRef {
        Self::get_interface(service)
    }

    /// Connects to an RPC Binder server over inet socket at the given address and port.
    pub fn setup_inet_client<T: FromIBinder + ?Sized>(
        &self,
        address: &str,
        port: u32,
    ) -> Result<Strong<T>, StatusCode> {
        let address = match CString::new(address) {
            Ok(s) => s,
            Err(e) => {
                log::error!("Cannot convert {} to CString. Error: {:?}", address, e);
                return Err(StatusCode::BAD_VALUE);
            }
        };

        // SAFETY: AIBinder returned by ARpcSession_setupInet has correct reference
        // count, and the ownership can safely be taken by new_spibinder.
        let service = unsafe {
            new_spibinder(binder_rpc_unstable_bindgen::ARpcSession_setupInet(
                self.as_ptr(),
                address.as_ptr(),
                port,
            ))
        };
        Self::get_interface(service)
    }

    /// Connects to an RPC Binder server, using the given callback to get (and
    /// take ownership of) file descriptors already connected to it.
    pub fn setup_preconnected_client<T: FromIBinder + ?Sized>(