[rpc_binder] Implement RPC binder over init-managed Unix domain socket

This implements an RPC binder over init-managed Unix domain sockets.
The cl adds binder tests and the new API is also used for
vm_payload_service inside Microdroid.
A previous cl aosp/2229557 sets up the binder over anonymous Unix sockets.

Test: atest MicrodroidTests ComposHostTestCases
Bug: 222479468
Change-Id: I0c7c38f4792c4536f5f88eb7e035091505f782f7
diff --git a/libs/binder/rust/rpcbinder/Android.bp b/libs/binder/rust/rpcbinder/Android.bp
index 5ebc27f..9771cc9 100644
--- a/libs/binder/rust/rpcbinder/Android.bp
+++ b/libs/binder/rust/rpcbinder/Android.bp
@@ -20,6 +20,7 @@
         "libbinder_rs",
         "libdowncast_rs",
         "liblibc",
+        "liblog_rust",
     ],
     apex_available: [
         "com.android.compos",
diff --git a/libs/binder/rust/rpcbinder/src/client.rs b/libs/binder/rust/rpcbinder/src/client.rs
index 4343ff4..48c787b 100644
--- a/libs/binder/rust/rpcbinder/src/client.rs
+++ b/libs/binder/rust/rpcbinder/src/client.rs
@@ -15,6 +15,7 @@
  */
 
 use binder::{unstable_api::new_spibinder, FromIBinder, SpIBinder, StatusCode, Strong};
+use std::ffi::CString;
 use std::os::{
     raw::{c_int, c_void},
     unix::io::RawFd,
@@ -35,6 +36,27 @@
     interface_cast(get_vsock_rpc_service(cid, port))
 }
 
+/// Connects to an RPC Binder server over Unix domain socket.
+pub fn get_unix_domain_rpc_service(socket_name: &str) -> Option<SpIBinder> {
+    let socket_name = match CString::new(socket_name) {
+        Ok(s) => s,
+        Err(e) => {
+            log::error!("Cannot convert {} to CString. Error: {:?}", socket_name, e);
+            return None;
+        }
+    };
+    // SAFETY: AIBinder returned by UnixDomainRpcClient has correct reference count,
+    // and the ownership can safely be taken by new_spibinder.
+    unsafe { new_spibinder(binder_rpc_unstable_bindgen::UnixDomainRpcClient(socket_name.as_ptr())) }
+}
+
+/// Connects to an RPC Binder server for a particular interface over Unix domain socket.
+pub fn get_unix_domain_rpc_interface<T: FromIBinder + ?Sized>(
+    socket_name: &str,
+) -> Result<Strong<T>, StatusCode> {
+    interface_cast(get_unix_domain_rpc_service(socket_name))
+}
+
 /// Connects to an RPC Binder server, using the given callback to get (and take ownership of)
 /// file descriptors already connected to it.
 pub fn get_preconnected_rpc_service(
diff --git a/libs/binder/rust/rpcbinder/src/lib.rs b/libs/binder/rust/rpcbinder/src/lib.rs
index fb6b90c..89a49a4 100644
--- a/libs/binder/rust/rpcbinder/src/lib.rs
+++ b/libs/binder/rust/rpcbinder/src/lib.rs
@@ -20,7 +20,9 @@
 mod server;
 
 pub use client::{
-    get_preconnected_rpc_interface, get_preconnected_rpc_service, get_vsock_rpc_interface,
-    get_vsock_rpc_service,
+    get_preconnected_rpc_interface, get_preconnected_rpc_service, get_unix_domain_rpc_interface,
+    get_unix_domain_rpc_service, get_vsock_rpc_interface, get_vsock_rpc_service,
 };
-pub use server::{run_vsock_rpc_server, run_vsock_rpc_server_with_factory};
+pub use server::{
+    run_init_unix_domain_rpc_server, run_vsock_rpc_server, run_vsock_rpc_server_with_factory,
+};
diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs
index 8009297..b350a13 100644
--- a/libs/binder/rust/rpcbinder/src/server.rs
+++ b/libs/binder/rust/rpcbinder/src/server.rs
@@ -18,7 +18,7 @@
     unstable_api::{AIBinder, AsNative},
     SpIBinder,
 };
-use std::{os::raw, ptr::null_mut};
+use std::{ffi::CString, os::raw, ptr::null_mut};
 
 /// Runs a binder RPC server, serving the supplied binder service implementation on the given vsock
 /// port.
@@ -35,7 +35,28 @@
     F: FnOnce(),
 {
     let mut ready_notifier = ReadyNotifier(Some(on_ready));
-    ready_notifier.run_server(service, port)
+    ready_notifier.run_vsock_server(service, port)
+}
+
+/// Runs a binder RPC server, serving the supplied binder service implementation on the given
+/// socket file name. The socket should be initialized in init.rc with the same name.
+///
+/// If and when the server is ready for connections, `on_ready` is called to allow appropriate
+/// action to be taken - e.g. to notify clients that they may now attempt to connect.
+///
+/// The current thread is joined to the binder thread pool to handle incoming messages.
+///
+/// Returns true if the server has shutdown normally, false if it failed in some way.
+pub fn run_init_unix_domain_rpc_server<F>(
+    service: SpIBinder,
+    socket_name: &str,
+    on_ready: F,
+) -> bool
+where
+    F: FnOnce(),
+{
+    let mut ready_notifier = ReadyNotifier(Some(on_ready));
+    ready_notifier.run_init_unix_domain_server(service, socket_name)
 }
 
 struct ReadyNotifier<F>(Option<F>)
@@ -46,7 +67,7 @@
 where
     F: FnOnce(),
 {
-    fn run_server(&mut self, mut service: SpIBinder, port: u32) -> bool {
+    fn run_vsock_server(&mut self, mut service: SpIBinder, port: u32) -> bool {
         let service = service.as_native_mut();
         let param = self.as_void_ptr();
 
@@ -64,6 +85,31 @@
         }
     }
 
+    fn run_init_unix_domain_server(&mut self, mut service: SpIBinder, socket_name: &str) -> bool {
+        let socket_name = match CString::new(socket_name) {
+            Ok(s) => s,
+            Err(e) => {
+                log::error!("Cannot convert {} to CString. Error: {:?}", socket_name, e);
+                return false;
+            }
+        };
+        let service = service.as_native_mut();
+        let param = self.as_void_ptr();
+
+        // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
+        // Plus the binder objects are threadsafe.
+        // RunInitUnixDomainRpcServer does not retain a reference to `ready_callback` or `param`;
+        // it only uses them before it returns, which is during the lifetime of `self`.
+        unsafe {
+            binder_rpc_unstable_bindgen::RunInitUnixDomainRpcServer(
+                service,
+                socket_name.as_ptr(),
+                Some(Self::ready_callback),
+                param,
+            )
+        }
+    }
+
     fn as_void_ptr(&mut self) -> *mut raw::c_void {
         self as *mut _ as *mut raw::c_void
     }