binder: add is_handling_transaction tests

See also: aosp/1892698

Test: this commit adds tests
Change-Id: I0242de56df13491faf338d65c732509d37555fa0
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 40359b4..09a956d 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -100,6 +100,7 @@
     Test = FIRST_CALL_TRANSACTION,
     GetDumpArgs,
     GetSelinuxContext,
+    GetIsHandlingTransaction,
 }
 
 impl TryFrom<u32> for TestTransactionCode {
@@ -112,6 +113,7 @@
             _ if c == TestTransactionCode::GetSelinuxContext as u32 => {
                 Ok(TestTransactionCode::GetSelinuxContext)
             }
+            _ if c == TestTransactionCode::GetIsHandlingTransaction as u32 => Ok(TestTransactionCode::GetIsHandlingTransaction),
             _ => Err(StatusCode::UNKNOWN_TRANSACTION),
         }
     }
@@ -140,6 +142,10 @@
             ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned()));
         sid.ok_or(StatusCode::UNEXPECTED_NULL)
     }
+
+    fn get_is_handling_transaction(&self) -> binder::Result<bool> {
+        Ok(binder::is_handling_transaction())
+    }
 }
 
 /// Trivial testing binder interface
@@ -152,6 +158,9 @@
 
     /// Returns the caller's SELinux context
     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
@@ -164,6 +173,9 @@
 
     /// Returns the caller's SELinux context
     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! {
@@ -186,6 +198,7 @@
         TestTransactionCode::Test => reply.write(&service.test()?),
         TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?),
         TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?),
+        TestTransactionCode::GetIsHandlingTransaction => reply.write(&service.get_is_handling_transaction()?),
     }
 }
 
@@ -212,6 +225,15 @@
         )?;
         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 {
@@ -238,6 +260,14 @@
             |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> {
@@ -252,6 +282,10 @@
     fn get_selinux_context(&self) -> binder::Result<String> {
         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> {
@@ -269,6 +303,11 @@
         let res = self.0.get_selinux_context();
         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
@@ -500,7 +539,7 @@
 
     #[tokio::test]
     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 test_client: Strong<dyn IATest<Tokio>> =
             binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service");
@@ -867,4 +906,45 @@
             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();
+    }
 }