diff options
Diffstat (limited to 'libs/binder/rust/rpcbinder/src/server.rs')
-rw-r--r-- | libs/binder/rust/rpcbinder/src/server.rs | 162 |
1 files changed, 7 insertions, 155 deletions
diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs index 6fda878d07..d6bdbd831f 100644 --- a/libs/binder/rust/rpcbinder/src/server.rs +++ b/libs/binder/rust/rpcbinder/src/server.rs @@ -14,160 +14,12 @@ * limitations under the License. */ -use crate::session::FileDescriptorTransportMode; -use binder::{unstable_api::AsNative, SpIBinder}; -use binder_rpc_unstable_bindgen::ARpcServer; -use foreign_types::{foreign_type, ForeignType, ForeignTypeRef}; -use std::ffi::CString; -use std::io::{Error, ErrorKind}; -use std::os::unix::io::{IntoRawFd, OwnedFd}; - -foreign_type! { - type CType = binder_rpc_unstable_bindgen::ARpcServer; - fn drop = binder_rpc_unstable_bindgen::ARpcServer_free; - - /// A type that represents a foreign instance of RpcServer. - #[derive(Debug)] - pub struct RpcServer; - /// A borrowed RpcServer. - pub struct RpcServerRef; -} - -/// SAFETY: The opaque handle can be cloned freely. -unsafe impl Send for RpcServer {} -/// SAFETY: The underlying C++ RpcServer class is thread-safe. -unsafe impl Sync for RpcServer {} - -impl RpcServer { - /// Creates a binder RPC server, serving the supplied binder service implementation on the given - /// vsock port. Only connections from the given CID are accepted. - /// - // Set `cid` to libc::VMADDR_CID_ANY to accept connections from any client. - // Set `cid` to libc::VMADDR_CID_LOCAL to only bind to the local vsock interface. - pub fn new_vsock(mut service: SpIBinder, cid: u32, port: u32) -> Result<RpcServer, Error> { - 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_newVsock( - service, cid, port, - )) - } - } - - /// Creates a binder RPC server, serving the supplied binder service implementation on the given - /// socket file descriptor. The socket should be bound to an address before calling this - /// function. - pub fn new_bound_socket( - mut service: SpIBinder, - socket_fd: OwnedFd, - ) -> Result<RpcServer, Error> { - 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. - // The server takes ownership of the socket FD. - unsafe { - Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newBoundSocket( - service, - socket_fd.into_raw_fd(), - )) - } - } - - /// Creates a binder RPC server that bootstraps sessions using an existing Unix domain socket - /// pair, with a given root IBinder object. Callers should create a pair of SOCK_STREAM Unix - /// domain sockets, pass one to the server and the other to the client. Multiple client session - /// can be created from the client end of the pair. - pub fn new_unix_domain_bootstrap( - mut service: SpIBinder, - bootstrap_fd: OwnedFd, - ) -> Result<RpcServer, Error> { - 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. - // The server takes ownership of the bootstrap FD. - unsafe { - Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newUnixDomainBootstrap( - service, - bootstrap_fd.into_raw_fd(), - )) - } - } - - /// 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")); - } - // SAFETY: Our caller must pass us a valid or null pointer, and we've checked that it's not - // null. - Ok(unsafe { RpcServer::from_ptr(ptr) }) - } -} - -impl RpcServerRef { - /// Sets the list of file descriptor transport modes supported by this server. - pub fn set_supported_file_descriptor_transport_modes( - &self, - modes: &[FileDescriptorTransportMode], - ) { - // SAFETY: Does not keep the pointer after returning does, nor does it - // read past its boundary. Only passes the 'self' pointer as an opaque handle. - unsafe { - binder_rpc_unstable_bindgen::ARpcServer_setSupportedFileDescriptorTransportModes( - self.as_ptr(), - modes.as_ptr(), - modes.len(), - ) - } - } - - /// Starts a new background thread and calls join(). Returns immediately. - pub fn start(&self) { - // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer. - unsafe { binder_rpc_unstable_bindgen::ARpcServer_start(self.as_ptr()) }; - } - - /// Joins the RpcServer thread. The call blocks until the server terminates. - /// This must be called from exactly one thread. - pub fn join(&self) { - // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer. - unsafe { binder_rpc_unstable_bindgen::ARpcServer_join(self.as_ptr()) }; - } - - /// Shuts down the running RpcServer. Can be called multiple times and from - /// multiple threads. Called automatically during drop(). - pub fn shutdown(&self) -> Result<(), Error> { - // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer. - if unsafe { binder_rpc_unstable_bindgen::ARpcServer_shutdown(self.as_ptr()) } { - Ok(()) - } else { - Err(Error::from(ErrorKind::UnexpectedEof)) - } +cfg_if::cfg_if! { + if #[cfg(target_os = "trusty")] { + mod trusty; + pub use trusty::*; + } else { + mod android; + pub use android::*; } } |