diff options
Diffstat (limited to 'libs/binder/rust/binder_tokio/lib.rs')
-rw-r--r-- | libs/binder/rust/binder_tokio/lib.rs | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/libs/binder/rust/binder_tokio/lib.rs b/libs/binder/rust/binder_tokio/lib.rs index 1dc0b2471d..71bb95bc0e 100644 --- a/libs/binder/rust/binder_tokio/lib.rs +++ b/libs/binder/rust/binder_tokio/lib.rs @@ -34,6 +34,7 @@ use std::future::Future; /// Retrieve an existing service for a particular interface, sleeping for a few /// seconds if it doesn't yet exist. +#[deprecated = "this polls 5s, use wait_for_interface or check_interface"] pub async fn get_interface<T: FromIBinder + ?Sized + 'static>( name: &str, ) -> Result<Strong<T>, StatusCode> { @@ -56,6 +57,32 @@ pub async fn get_interface<T: FromIBinder + ?Sized + 'static>( } } +/// Retrieve an existing service for a particular interface. Returns +/// `Err(StatusCode::NAME_NOT_FOUND)` immediately if the service is not available. +/// +/// NOTE: "immediately" above does not mean the future will complete the first time it is polled. +pub async fn check_interface<T: FromIBinder + ?Sized + 'static>( + name: &str, +) -> Result<Strong<T>, StatusCode> { + if binder::is_handling_transaction() { + // See comment in the BinderAsyncPool impl. + return binder::check_interface::<T>(name); + } + + let name = name.to_string(); + let res = tokio::task::spawn_blocking(move || binder::check_interface::<T>(&name)).await; + + // The `is_panic` branch is not actually reachable in Android as we compile + // with `panic = abort`. + match res { + Ok(Ok(service)) => Ok(service), + Ok(Err(err)) => Err(err), + Err(e) if e.is_panic() => std::panic::resume_unwind(e.into_panic()), + Err(e) if e.is_cancelled() => Err(StatusCode::FAILED_TRANSACTION), + Err(_) => Err(StatusCode::UNKNOWN_ERROR), + } +} + /// Retrieve an existing service for a particular interface, or start it if it /// is configured as a dynamic service and isn't yet started. pub async fn wait_for_interface<T: FromIBinder + ?Sized + 'static>( |