Loading libs/binder/rust/src/binder.rs +57 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,35 @@ pub trait Interface: Send + Sync { } } /// Implemented by sync interfaces to specify what the associated async interface is. /// Generic to handle the fact that async interfaces are generic over a thread pool. /// /// The binder in any object implementing this trait should be compatible with the /// `Target` associated type, and using `FromIBinder` to convert it to the target /// should not fail. pub trait ToAsyncInterface<P> where Self: Interface, Self::Target: FromIBinder, { /// The async interface associated with this sync interface. type Target: ?Sized; } /// Implemented by async interfaces to specify what the associated sync interface is. /// /// The binder in any object implementing this trait should be compatible with the /// `Target` associated type, and using `FromIBinder` to convert it to the target /// should not fail. pub trait ToSyncInterface where Self: Interface, Self::Target: FromIBinder, { /// The sync interface associated with this async interface. type Target: ?Sized; } /// Interface stability promise /// /// An interface can promise to be a stable vendor interface ([`Vintf`]), or Loading Loading @@ -337,6 +366,26 @@ impl<I: FromIBinder + ?Sized> Strong<I> { pub fn downgrade(this: &Strong<I>) -> Weak<I> { Weak::new(this) } /// Convert this synchronous binder handle into an asynchronous one. pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target> where I: ToAsyncInterface<P>, { // By implementing the ToAsyncInterface trait, it is guaranteed that the binder // object is also valid for the target type. FromIBinder::try_from(self.0.as_binder()).unwrap() } /// Convert this asynchronous binder handle into a synchronous one. pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target> where I: ToSyncInterface, { // By implementing the ToSyncInterface trait, it is guaranteed that the binder // object is also valid for the target type. FromIBinder::try_from(self.0.as_binder()).unwrap() } } impl<I: FromIBinder + ?Sized> Clone for Strong<I> { Loading Loading @@ -1017,6 +1066,14 @@ macro_rules! declare_binder_interface { .expect(concat!("Error cloning interface ", stringify!($async_interface))) } } impl<P: $crate::BinderAsyncPool> $crate::ToAsyncInterface<P> for dyn $interface { type Target = dyn $async_interface<P>; } impl<P: $crate::BinderAsyncPool> $crate::ToSyncInterface for dyn $async_interface<P> { type Target = dyn $interface; } )? }; } Loading libs/binder/rust/src/lib.rs +2 −2 Original line number Diff line number Diff line Loading @@ -109,8 +109,8 @@ pub mod parcel; pub use crate::binder::{ BinderFeatures, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable, Stability, Strong, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, Stability, Strong, ToAsyncInterface, ToSyncInterface, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, }; pub use crate::binder_async::{BoxFuture, BinderAsyncPool}; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; Loading libs/binder/rust/tests/integration.rs +26 −0 Original line number Diff line number Diff line Loading @@ -549,6 +549,32 @@ mod tests { ); } #[tokio::test] async fn get_selinux_context_sync_to_async() { let service_name = "get_selinux_context"; let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn ITest> = binder::get_interface(service_name).expect("Did not get manager binder service"); let test_client = test_client.into_async::<Tokio>(); assert_eq!( test_client.get_selinux_context().await.unwrap(), get_expected_selinux_context() ); } #[tokio::test] async fn get_selinux_context_async_to_sync() { let service_name = "get_selinux_context"; let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service"); let test_client = test_client.into_sync(); assert_eq!( test_client.get_selinux_context().unwrap(), get_expected_selinux_context() ); } struct Bools { binder_died: Arc<AtomicBool>, binder_dealloc: Arc<AtomicBool>, Loading Loading
libs/binder/rust/src/binder.rs +57 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,35 @@ pub trait Interface: Send + Sync { } } /// Implemented by sync interfaces to specify what the associated async interface is. /// Generic to handle the fact that async interfaces are generic over a thread pool. /// /// The binder in any object implementing this trait should be compatible with the /// `Target` associated type, and using `FromIBinder` to convert it to the target /// should not fail. pub trait ToAsyncInterface<P> where Self: Interface, Self::Target: FromIBinder, { /// The async interface associated with this sync interface. type Target: ?Sized; } /// Implemented by async interfaces to specify what the associated sync interface is. /// /// The binder in any object implementing this trait should be compatible with the /// `Target` associated type, and using `FromIBinder` to convert it to the target /// should not fail. pub trait ToSyncInterface where Self: Interface, Self::Target: FromIBinder, { /// The sync interface associated with this async interface. type Target: ?Sized; } /// Interface stability promise /// /// An interface can promise to be a stable vendor interface ([`Vintf`]), or Loading Loading @@ -337,6 +366,26 @@ impl<I: FromIBinder + ?Sized> Strong<I> { pub fn downgrade(this: &Strong<I>) -> Weak<I> { Weak::new(this) } /// Convert this synchronous binder handle into an asynchronous one. pub fn into_async<P>(self) -> Strong<<I as ToAsyncInterface<P>>::Target> where I: ToAsyncInterface<P>, { // By implementing the ToAsyncInterface trait, it is guaranteed that the binder // object is also valid for the target type. FromIBinder::try_from(self.0.as_binder()).unwrap() } /// Convert this asynchronous binder handle into a synchronous one. pub fn into_sync(self) -> Strong<<I as ToSyncInterface>::Target> where I: ToSyncInterface, { // By implementing the ToSyncInterface trait, it is guaranteed that the binder // object is also valid for the target type. FromIBinder::try_from(self.0.as_binder()).unwrap() } } impl<I: FromIBinder + ?Sized> Clone for Strong<I> { Loading Loading @@ -1017,6 +1066,14 @@ macro_rules! declare_binder_interface { .expect(concat!("Error cloning interface ", stringify!($async_interface))) } } impl<P: $crate::BinderAsyncPool> $crate::ToAsyncInterface<P> for dyn $interface { type Target = dyn $async_interface<P>; } impl<P: $crate::BinderAsyncPool> $crate::ToSyncInterface for dyn $async_interface<P> { type Target = dyn $interface; } )? }; } Loading
libs/binder/rust/src/lib.rs +2 −2 Original line number Diff line number Diff line Loading @@ -109,8 +109,8 @@ pub mod parcel; pub use crate::binder::{ BinderFeatures, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable, Stability, Strong, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, Stability, Strong, ToAsyncInterface, ToSyncInterface, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, }; pub use crate::binder_async::{BoxFuture, BinderAsyncPool}; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; Loading
libs/binder/rust/tests/integration.rs +26 −0 Original line number Diff line number Diff line Loading @@ -549,6 +549,32 @@ mod tests { ); } #[tokio::test] async fn get_selinux_context_sync_to_async() { let service_name = "get_selinux_context"; let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn ITest> = binder::get_interface(service_name).expect("Did not get manager binder service"); let test_client = test_client.into_async::<Tokio>(); assert_eq!( test_client.get_selinux_context().await.unwrap(), get_expected_selinux_context() ); } #[tokio::test] async fn get_selinux_context_async_to_sync() { let service_name = "get_selinux_context"; let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service"); let test_client = test_client.into_sync(); assert_eq!( test_client.get_selinux_context().unwrap(), get_expected_selinux_context() ); } struct Bools { binder_died: Arc<AtomicBool>, binder_dealloc: Arc<AtomicBool>, Loading