Loading libs/binder/rust/tests/integration.rs +81 −1 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,7 @@ enum TestTransactionCode { Test = FIRST_CALL_TRANSACTION, Test = FIRST_CALL_TRANSACTION, GetDumpArgs, GetDumpArgs, GetSelinuxContext, GetSelinuxContext, GetIsHandlingTransaction, } } impl TryFrom<u32> for TestTransactionCode { impl TryFrom<u32> for TestTransactionCode { Loading @@ -112,6 +113,7 @@ impl TryFrom<u32> for TestTransactionCode { _ if c == TestTransactionCode::GetSelinuxContext as u32 => { _ if c == TestTransactionCode::GetSelinuxContext as u32 => { Ok(TestTransactionCode::GetSelinuxContext) Ok(TestTransactionCode::GetSelinuxContext) } } _ if c == TestTransactionCode::GetIsHandlingTransaction as u32 => Ok(TestTransactionCode::GetIsHandlingTransaction), _ => Err(StatusCode::UNKNOWN_TRANSACTION), _ => Err(StatusCode::UNKNOWN_TRANSACTION), } } } } Loading Loading @@ -140,6 +142,10 @@ impl ITest for TestService { ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned())); ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned())); sid.ok_or(StatusCode::UNEXPECTED_NULL) sid.ok_or(StatusCode::UNEXPECTED_NULL) } } fn get_is_handling_transaction(&self) -> binder::Result<bool> { Ok(binder::is_handling_transaction()) } } } /// Trivial testing binder interface /// Trivial testing binder interface Loading @@ -152,6 +158,9 @@ pub trait ITest: Interface { /// Returns the caller's SELinux context /// Returns the caller's SELinux context fn get_selinux_context(&self) -> binder::Result<String>; fn get_selinux_context(&self) -> binder::Result<String>; /// Returns the value of calling `is_handling_transaction`. fn get_is_handling_transaction(&self) -> binder::Result<bool>; } } /// Async trivial testing binder interface /// Async trivial testing binder interface Loading @@ -164,6 +173,9 @@ pub trait IATest<P>: Interface { /// Returns the caller's SELinux context /// Returns the caller's SELinux context fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>>; fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>>; /// Returns the value of calling `is_handling_transaction`. fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>>; } } declare_binder_interface! { declare_binder_interface! { Loading @@ -186,6 +198,7 @@ fn on_transact( TestTransactionCode::Test => reply.write(&service.test()?), TestTransactionCode::Test => reply.write(&service.test()?), TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?), TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?), TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?), TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?), TestTransactionCode::GetIsHandlingTransaction => reply.write(&service.get_is_handling_transaction()?), } } } } Loading @@ -212,6 +225,15 @@ impl ITest for BpTest { )?; )?; reply.read() reply.read() } } fn get_is_handling_transaction(&self) -> binder::Result<bool> { let reply = self.binder.transact( TestTransactionCode::GetIsHandlingTransaction as TransactionCode, 0, |_| Ok(()), )?; reply.read() } } } impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { Loading @@ -238,6 +260,14 @@ impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { |reply| async move { reply?.read() } |reply| async move { reply?.read() } ) ) } } fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>> { let binder = self.binder.clone(); P::spawn( move || binder.transact(TestTransactionCode::GetIsHandlingTransaction as TransactionCode, 0, |_| Ok(())), |reply| async move { reply?.read() } ) } } } impl ITest for Binder<BnTest> { impl ITest for Binder<BnTest> { Loading @@ -252,6 +282,10 @@ impl ITest for Binder<BnTest> { fn get_selinux_context(&self) -> binder::Result<String> { fn get_selinux_context(&self) -> binder::Result<String> { self.0.get_selinux_context() self.0.get_selinux_context() } } fn get_is_handling_transaction(&self) -> binder::Result<bool> { self.0.get_is_handling_transaction() } } } impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> { impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> { Loading @@ -269,6 +303,11 @@ impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> { let res = self.0.get_selinux_context(); let res = self.0.get_selinux_context(); Box::pin(async move { res }) Box::pin(async move { res }) } } fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>> { let res = self.0.get_is_handling_transaction(); Box::pin(async move { res }) } } } /// Trivial testing binder interface /// Trivial testing binder interface Loading Loading @@ -500,7 +539,7 @@ mod tests { #[tokio::test] #[tokio::test] async fn get_selinux_context_async() { async fn get_selinux_context_async() { let service_name = "get_selinux_context"; let service_name = "get_selinux_context_async"; let _process = ScopedServiceProcess::new(service_name); let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn IATest<Tokio>> = let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service"); binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service"); Loading Loading @@ -867,4 +906,45 @@ mod tests { Err(err) => assert_eq!(err, binder::StatusCode::BAD_VALUE), Err(err) => assert_eq!(err, binder::StatusCode::BAD_VALUE), } } } } #[test] fn get_is_handling_transaction() { let service_name = "get_is_handling_transaction"; let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn ITest> = binder::get_interface(service_name).expect("Did not get manager binder service"); // Should be true externally. assert!(test_client.get_is_handling_transaction().unwrap()); // Should be false locally. assert!(!binder::is_handling_transaction()); // Should also be false in spawned thread. std::thread::spawn(|| { assert!(!binder::is_handling_transaction()); }).join().unwrap(); } #[tokio::test] async fn get_is_handling_transaction_async() { let service_name = "get_is_handling_transaction_async"; 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"); // Should be true externally. assert!(test_client.get_is_handling_transaction().await.unwrap()); // Should be false locally. assert!(!binder::is_handling_transaction()); // Should also be false in spawned task. tokio::spawn(async { assert!(!binder::is_handling_transaction()); }).await.unwrap(); // And in spawn_blocking task. tokio::task::spawn_blocking(|| { assert!(!binder::is_handling_transaction()); }).await.unwrap(); } } } Loading
libs/binder/rust/tests/integration.rs +81 −1 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,7 @@ enum TestTransactionCode { Test = FIRST_CALL_TRANSACTION, Test = FIRST_CALL_TRANSACTION, GetDumpArgs, GetDumpArgs, GetSelinuxContext, GetSelinuxContext, GetIsHandlingTransaction, } } impl TryFrom<u32> for TestTransactionCode { impl TryFrom<u32> for TestTransactionCode { Loading @@ -112,6 +113,7 @@ impl TryFrom<u32> for TestTransactionCode { _ if c == TestTransactionCode::GetSelinuxContext as u32 => { _ if c == TestTransactionCode::GetSelinuxContext as u32 => { Ok(TestTransactionCode::GetSelinuxContext) Ok(TestTransactionCode::GetSelinuxContext) } } _ if c == TestTransactionCode::GetIsHandlingTransaction as u32 => Ok(TestTransactionCode::GetIsHandlingTransaction), _ => Err(StatusCode::UNKNOWN_TRANSACTION), _ => Err(StatusCode::UNKNOWN_TRANSACTION), } } } } Loading Loading @@ -140,6 +142,10 @@ impl ITest for TestService { ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned())); ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned())); sid.ok_or(StatusCode::UNEXPECTED_NULL) sid.ok_or(StatusCode::UNEXPECTED_NULL) } } fn get_is_handling_transaction(&self) -> binder::Result<bool> { Ok(binder::is_handling_transaction()) } } } /// Trivial testing binder interface /// Trivial testing binder interface Loading @@ -152,6 +158,9 @@ pub trait ITest: Interface { /// Returns the caller's SELinux context /// Returns the caller's SELinux context fn get_selinux_context(&self) -> binder::Result<String>; fn get_selinux_context(&self) -> binder::Result<String>; /// Returns the value of calling `is_handling_transaction`. fn get_is_handling_transaction(&self) -> binder::Result<bool>; } } /// Async trivial testing binder interface /// Async trivial testing binder interface Loading @@ -164,6 +173,9 @@ pub trait IATest<P>: Interface { /// Returns the caller's SELinux context /// Returns the caller's SELinux context fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>>; fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>>; /// Returns the value of calling `is_handling_transaction`. fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>>; } } declare_binder_interface! { declare_binder_interface! { Loading @@ -186,6 +198,7 @@ fn on_transact( TestTransactionCode::Test => reply.write(&service.test()?), TestTransactionCode::Test => reply.write(&service.test()?), TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?), TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?), TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?), TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?), TestTransactionCode::GetIsHandlingTransaction => reply.write(&service.get_is_handling_transaction()?), } } } } Loading @@ -212,6 +225,15 @@ impl ITest for BpTest { )?; )?; reply.read() reply.read() } } fn get_is_handling_transaction(&self) -> binder::Result<bool> { let reply = self.binder.transact( TestTransactionCode::GetIsHandlingTransaction as TransactionCode, 0, |_| Ok(()), )?; reply.read() } } } impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { Loading @@ -238,6 +260,14 @@ impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { |reply| async move { reply?.read() } |reply| async move { reply?.read() } ) ) } } fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>> { let binder = self.binder.clone(); P::spawn( move || binder.transact(TestTransactionCode::GetIsHandlingTransaction as TransactionCode, 0, |_| Ok(())), |reply| async move { reply?.read() } ) } } } impl ITest for Binder<BnTest> { impl ITest for Binder<BnTest> { Loading @@ -252,6 +282,10 @@ impl ITest for Binder<BnTest> { fn get_selinux_context(&self) -> binder::Result<String> { fn get_selinux_context(&self) -> binder::Result<String> { self.0.get_selinux_context() self.0.get_selinux_context() } } fn get_is_handling_transaction(&self) -> binder::Result<bool> { self.0.get_is_handling_transaction() } } } impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> { impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> { Loading @@ -269,6 +303,11 @@ impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> { let res = self.0.get_selinux_context(); let res = self.0.get_selinux_context(); Box::pin(async move { res }) Box::pin(async move { res }) } } fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>> { let res = self.0.get_is_handling_transaction(); Box::pin(async move { res }) } } } /// Trivial testing binder interface /// Trivial testing binder interface Loading Loading @@ -500,7 +539,7 @@ mod tests { #[tokio::test] #[tokio::test] async fn get_selinux_context_async() { async fn get_selinux_context_async() { let service_name = "get_selinux_context"; let service_name = "get_selinux_context_async"; let _process = ScopedServiceProcess::new(service_name); let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn IATest<Tokio>> = let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service"); binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service"); Loading Loading @@ -867,4 +906,45 @@ mod tests { Err(err) => assert_eq!(err, binder::StatusCode::BAD_VALUE), Err(err) => assert_eq!(err, binder::StatusCode::BAD_VALUE), } } } } #[test] fn get_is_handling_transaction() { let service_name = "get_is_handling_transaction"; let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn ITest> = binder::get_interface(service_name).expect("Did not get manager binder service"); // Should be true externally. assert!(test_client.get_is_handling_transaction().unwrap()); // Should be false locally. assert!(!binder::is_handling_transaction()); // Should also be false in spawned thread. std::thread::spawn(|| { assert!(!binder::is_handling_transaction()); }).join().unwrap(); } #[tokio::test] async fn get_is_handling_transaction_async() { let service_name = "get_is_handling_transaction_async"; 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"); // Should be true externally. assert!(test_client.get_is_handling_transaction().await.unwrap()); // Should be false locally. assert!(!binder::is_handling_transaction()); // Should also be false in spawned task. tokio::spawn(async { assert!(!binder::is_handling_transaction()); }).await.unwrap(); // And in spawn_blocking task. tokio::task::spawn_blocking(|| { assert!(!binder::is_handling_transaction()); }).await.unwrap(); } } }