Extract run_rpc_server to libbinder_common

We have two very similar uses of RunRpcServerCallback; extract them to
a common place, using a closure to encapsulate the specific behavior
for notifiying readiness.

This also neatly encapsulates all the unsafe code, and justification
of it, in one place.

Bug: 187444679
Test: atest ComposTestCase
Change-Id: If23f862748b2f921690820eaa6ee80e4b2829274
diff --git a/authfs/fd_server/src/main.rs b/authfs/fd_server/src/main.rs
index 32ffc0a..395e2e9 100644
--- a/authfs/fd_server/src/main.rs
+++ b/authfs/fd_server/src/main.rs
@@ -25,14 +25,13 @@
 mod fsverity;
 
 use anyhow::{bail, Result};
-use binder::unstable_api::AsNative;
+use binder_common::rpc_server::run_rpc_server;
 use log::{debug, error};
 use std::cmp::min;
 use std::collections::BTreeMap;
 use std::convert::TryInto;
 use std::fs::File;
 use std::io;
-use std::os::raw;
 use std::os::unix::fs::FileExt;
 use std::os::unix::io::{AsRawFd, FromRawFd};
 
@@ -342,23 +341,17 @@
     );
 
     let args = parse_args()?;
-
-    let mut service = FdService::new_binder(args.fd_pool).as_binder();
-    let mut ready_notifier = ReadyNotifier(args.ready_fd);
+    let service = FdService::new_binder(args.fd_pool).as_binder();
 
     debug!("fd_server is starting as a rpc service.");
-    // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
-    // Plus the binder objects are threadsafe.
-    // RunRpcServerCallback does not retain a reference to ready_callback, and only ever
-    // calls it with the param we provide during the lifetime of ready_notifier.
-    let retval = unsafe {
-        binder_rpc_unstable_bindgen::RunRpcServerCallback(
-            service.as_native_mut() as *mut binder_rpc_unstable_bindgen::AIBinder,
-            RPC_SERVICE_PORT,
-            Some(ReadyNotifier::ready_callback),
-            ready_notifier.as_void_ptr(),
-        )
-    };
+
+    let mut ready_fd = args.ready_fd;
+    let retval = run_rpc_server(service, RPC_SERVICE_PORT, || {
+        debug!("fd_server is ready");
+        // Close the ready-fd if we were given one to signal our readiness.
+        drop(ready_fd.take());
+    });
+
     if retval {
         debug!("RPC server has shut down gracefully");
         Ok(())
@@ -366,25 +359,3 @@
         bail!("Premature termination of RPC server");
     }
 }
-
-struct ReadyNotifier(Option<File>);
-
-impl ReadyNotifier {
-    fn notify(&mut self) {
-        debug!("fd_server is ready");
-        // Close the ready-fd if we were given one to signal our readiness.
-        drop(self.0.take());
-    }
-
-    fn as_void_ptr(&mut self) -> *mut raw::c_void {
-        self as *mut _ as *mut raw::c_void
-    }
-
-    unsafe extern "C" fn ready_callback(param: *mut raw::c_void) {
-        // SAFETY: This is only ever called by RunRpcServerCallback, within the lifetime of the
-        // ReadyNotifier, with param taking the value returned by as_void_ptr (so a properly aligned
-        // non-null pointer to an initialized instance).
-        let ready_notifier = param as *mut Self;
-        ready_notifier.as_mut().unwrap().notify()
-    }
-}