1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! Rust Binder crate integration tests
18 
19 use binder::{declare_binder_enum, declare_binder_interface};
20 use binder::{BinderFeatures, Interface, StatusCode, ThreadState};
21 // Import from internal API for testing only, do not use this module in
22 // production.
23 use binder::binder_impl::{
24     Binder, BorrowedParcel, IBinderInternal, TransactionCode, FIRST_CALL_TRANSACTION,
25 };
26 
27 use std::convert::{TryFrom, TryInto};
28 use std::ffi::CStr;
29 use std::io::Write;
30 use std::sync::Mutex;
31 
32 /// Name of service runner.
33 ///
34 /// Must match the binary name in Android.bp
35 const RUST_SERVICE_BINARY: &str = "rustBinderTestService";
36 
37 /// Binary to run a test service.
38 ///
39 /// This needs to be in a separate process from the tests, so we spawn this
40 /// binary as a child, providing the service name as an argument.
main() -> Result<(), &'static str>41 fn main() -> Result<(), &'static str> {
42     // Ensure that we can handle all transactions on the main thread.
43     binder::ProcessState::set_thread_pool_max_thread_count(0);
44     binder::ProcessState::start_thread_pool();
45 
46     let mut args = std::env::args().skip(1);
47     if args.len() < 1 || args.len() > 2 {
48         print_usage();
49         return Err("");
50     }
51     let service_name = args.next().ok_or_else(|| {
52         print_usage();
53         "Missing SERVICE_NAME argument"
54     })?;
55     let extension_name = args.next();
56 
57     {
58         let mut service = Binder::new(BnTest(Box::new(TestService::new(&service_name))));
59         service.set_requesting_sid(true);
60         if let Some(extension_name) = extension_name {
61             let extension =
62                 BnTest::new_binder(TestService::new(&extension_name), BinderFeatures::default());
63             service.set_extension(&mut extension.as_binder()).expect("Could not add extension");
64         }
65         binder::add_service(&service_name, service.as_binder())
66             .expect("Could not register service");
67     }
68 
69     binder::ProcessState::join_thread_pool();
70     Err("Unexpected exit after join_thread_pool")
71 }
72 
print_usage()73 fn print_usage() {
74     eprintln!("Usage: {} SERVICE_NAME [EXTENSION_NAME]", RUST_SERVICE_BINARY);
75     eprintln!(concat!(
76         "Spawn a Binder test service identified by SERVICE_NAME,",
77         " optionally with an extesion named EXTENSION_NAME",
78     ));
79 }
80 
81 struct TestService {
82     s: String,
83     dump_args: Mutex<Vec<String>>,
84 }
85 
86 impl TestService {
new(s: &str) -> Self87     fn new(s: &str) -> Self {
88         Self { s: s.to_string(), dump_args: Mutex::new(Vec::new()) }
89     }
90 }
91 
92 #[repr(u32)]
93 enum TestTransactionCode {
94     Test = FIRST_CALL_TRANSACTION,
95     GetDumpArgs,
96     GetSelinuxContext,
97     GetIsHandlingTransaction,
98 }
99 
100 impl TryFrom<u32> for TestTransactionCode {
101     type Error = StatusCode;
102 
try_from(c: u32) -> Result<Self, Self::Error>103     fn try_from(c: u32) -> Result<Self, Self::Error> {
104         match c {
105             _ if c == TestTransactionCode::Test as u32 => Ok(TestTransactionCode::Test),
106             _ if c == TestTransactionCode::GetDumpArgs as u32 => {
107                 Ok(TestTransactionCode::GetDumpArgs)
108             }
109             _ if c == TestTransactionCode::GetSelinuxContext as u32 => {
110                 Ok(TestTransactionCode::GetSelinuxContext)
111             }
112             _ if c == TestTransactionCode::GetIsHandlingTransaction as u32 => {
113                 Ok(TestTransactionCode::GetIsHandlingTransaction)
114             }
115             _ => Err(StatusCode::UNKNOWN_TRANSACTION),
116         }
117     }
118 }
119 
120 impl Interface for TestService {
dump(&self, _writer: &mut dyn Write, args: &[&CStr]) -> Result<(), StatusCode>121     fn dump(&self, _writer: &mut dyn Write, args: &[&CStr]) -> Result<(), StatusCode> {
122         let mut dump_args = self.dump_args.lock().unwrap();
123         dump_args.extend(args.iter().map(|s| s.to_str().unwrap().to_owned()));
124         Ok(())
125     }
126 }
127 
128 impl ITest for TestService {
test(&self) -> Result<String, StatusCode>129     fn test(&self) -> Result<String, StatusCode> {
130         Ok(self.s.clone())
131     }
132 
get_dump_args(&self) -> Result<Vec<String>, StatusCode>133     fn get_dump_args(&self) -> Result<Vec<String>, StatusCode> {
134         let args = self.dump_args.lock().unwrap().clone();
135         Ok(args)
136     }
137 
get_selinux_context(&self) -> Result<String, StatusCode>138     fn get_selinux_context(&self) -> Result<String, StatusCode> {
139         let sid =
140             ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned()));
141         sid.ok_or(StatusCode::UNEXPECTED_NULL)
142     }
143 
get_is_handling_transaction(&self) -> Result<bool, StatusCode>144     fn get_is_handling_transaction(&self) -> Result<bool, StatusCode> {
145         Ok(binder::is_handling_transaction())
146     }
147 }
148 
149 /// Trivial testing binder interface
150 pub trait ITest: Interface {
151     /// Returns a test string
test(&self) -> Result<String, StatusCode>152     fn test(&self) -> Result<String, StatusCode>;
153 
154     /// Return the arguments sent via dump
get_dump_args(&self) -> Result<Vec<String>, StatusCode>155     fn get_dump_args(&self) -> Result<Vec<String>, StatusCode>;
156 
157     /// Returns the caller's SELinux context
get_selinux_context(&self) -> Result<String, StatusCode>158     fn get_selinux_context(&self) -> Result<String, StatusCode>;
159 
160     /// Returns the value of calling `is_handling_transaction`.
get_is_handling_transaction(&self) -> Result<bool, StatusCode>161     fn get_is_handling_transaction(&self) -> Result<bool, StatusCode>;
162 }
163 
164 /// Async trivial testing binder interface
165 pub trait IATest<P>: Interface {
166     /// Returns a test string
test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>167     fn test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>;
168 
169     /// Return the arguments sent via dump
get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>>170     fn get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>>;
171 
172     /// Returns the caller's SELinux context
get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>173     fn get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>;
174 
175     /// Returns the value of calling `is_handling_transaction`.
get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>>176     fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>>;
177 }
178 
179 declare_binder_interface! {
180     ITest["android.os.ITest"] {
181         native: BnTest(on_transact),
182         proxy: BpTest {
183             x: i32 = 100
184         },
185         async: IATest,
186     }
187 }
188 
on_transact( service: &dyn ITest, code: TransactionCode, _data: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>, ) -> Result<(), StatusCode>189 fn on_transact(
190     service: &dyn ITest,
191     code: TransactionCode,
192     _data: &BorrowedParcel<'_>,
193     reply: &mut BorrowedParcel<'_>,
194 ) -> Result<(), StatusCode> {
195     match code.try_into()? {
196         TestTransactionCode::Test => reply.write(&service.test()?),
197         TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?),
198         TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?),
199         TestTransactionCode::GetIsHandlingTransaction => {
200             reply.write(&service.get_is_handling_transaction()?)
201         }
202     }
203 }
204 
205 impl ITest for BpTest {
test(&self) -> Result<String, StatusCode>206     fn test(&self) -> Result<String, StatusCode> {
207         let reply =
208             self.binder.transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(()))?;
209         reply.read()
210     }
211 
get_dump_args(&self) -> Result<Vec<String>, StatusCode>212     fn get_dump_args(&self) -> Result<Vec<String>, StatusCode> {
213         let reply =
214             self.binder
215                 .transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(()))?;
216         reply.read()
217     }
218 
get_selinux_context(&self) -> Result<String, StatusCode>219     fn get_selinux_context(&self) -> Result<String, StatusCode> {
220         let reply = self.binder.transact(
221             TestTransactionCode::GetSelinuxContext as TransactionCode,
222             0,
223             |_| Ok(()),
224         )?;
225         reply.read()
226     }
227 
get_is_handling_transaction(&self) -> Result<bool, StatusCode>228     fn get_is_handling_transaction(&self) -> Result<bool, StatusCode> {
229         let reply = self.binder.transact(
230             TestTransactionCode::GetIsHandlingTransaction as TransactionCode,
231             0,
232             |_| Ok(()),
233         )?;
234         reply.read()
235     }
236 }
237 
238 impl<P: binder::BinderAsyncPool> IATest<P> for BpTest {
test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>239     fn test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>> {
240         let binder = self.binder.clone();
241         P::spawn(
242             move || binder.transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(())),
243             |reply| async move { reply?.read() },
244         )
245     }
246 
get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>>247     fn get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>> {
248         let binder = self.binder.clone();
249         P::spawn(
250             move || {
251                 binder.transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(()))
252             },
253             |reply| async move { reply?.read() },
254         )
255     }
256 
get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>257     fn get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>> {
258         let binder = self.binder.clone();
259         P::spawn(
260             move || {
261                 binder.transact(
262                     TestTransactionCode::GetSelinuxContext as TransactionCode,
263                     0,
264                     |_| Ok(()),
265                 )
266             },
267             |reply| async move { reply?.read() },
268         )
269     }
270 
get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>>271     fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>> {
272         let binder = self.binder.clone();
273         P::spawn(
274             move || {
275                 binder.transact(
276                     TestTransactionCode::GetIsHandlingTransaction as TransactionCode,
277                     0,
278                     |_| Ok(()),
279                 )
280             },
281             |reply| async move { reply?.read() },
282         )
283     }
284 }
285 
286 impl ITest for Binder<BnTest> {
test(&self) -> Result<String, StatusCode>287     fn test(&self) -> Result<String, StatusCode> {
288         self.0.test()
289     }
290 
get_dump_args(&self) -> Result<Vec<String>, StatusCode>291     fn get_dump_args(&self) -> Result<Vec<String>, StatusCode> {
292         self.0.get_dump_args()
293     }
294 
get_selinux_context(&self) -> Result<String, StatusCode>295     fn get_selinux_context(&self) -> Result<String, StatusCode> {
296         self.0.get_selinux_context()
297     }
298 
get_is_handling_transaction(&self) -> Result<bool, StatusCode>299     fn get_is_handling_transaction(&self) -> Result<bool, StatusCode> {
300         self.0.get_is_handling_transaction()
301     }
302 }
303 
304 impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> {
test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>305     fn test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>> {
306         let res = self.0.test();
307         Box::pin(async move { res })
308     }
309 
get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>>310     fn get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>> {
311         let res = self.0.get_dump_args();
312         Box::pin(async move { res })
313     }
314 
get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>315     fn get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>> {
316         let res = self.0.get_selinux_context();
317         Box::pin(async move { res })
318     }
319 
get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>>320     fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>> {
321         let res = self.0.get_is_handling_transaction();
322         Box::pin(async move { res })
323     }
324 }
325 
326 /// Trivial testing binder interface
327 pub trait ITestSameDescriptor: Interface {}
328 
329 declare_binder_interface! {
330     ITestSameDescriptor["android.os.ITest"] {
331         native: BnTestSameDescriptor(on_transact_same_descriptor),
332         proxy: BpTestSameDescriptor,
333     }
334 }
335 
on_transact_same_descriptor( _service: &dyn ITestSameDescriptor, _code: TransactionCode, _data: &BorrowedParcel<'_>, _reply: &mut BorrowedParcel<'_>, ) -> Result<(), StatusCode>336 fn on_transact_same_descriptor(
337     _service: &dyn ITestSameDescriptor,
338     _code: TransactionCode,
339     _data: &BorrowedParcel<'_>,
340     _reply: &mut BorrowedParcel<'_>,
341 ) -> Result<(), StatusCode> {
342     Ok(())
343 }
344 
345 impl ITestSameDescriptor for BpTestSameDescriptor {}
346 
347 impl ITestSameDescriptor for Binder<BnTestSameDescriptor> {}
348 
349 declare_binder_enum! {
350     TestEnum : [i32; 3] {
351         FOO = 1,
352         BAR = 2,
353         BAZ = 3,
354     }
355 }
356 
357 declare_binder_enum! {
358     #[deprecated(since = "1.0.0")]
359     TestDeprecatedEnum : [i32; 3] {
360         FOO = 1,
361         BAR = 2,
362         BAZ = 3,
363     }
364 }
365 
366 #[cfg(test)]
367 mod tests {
368     use selinux_bindgen as selinux_sys;
369     use std::ffi::CStr;
370     use std::fs::File;
371     use std::process::{Child, Command};
372     use std::ptr;
373     use std::sync::atomic::{AtomicBool, Ordering};
374     use std::sync::Arc;
375     use std::thread;
376     use std::time::Duration;
377 
378     use binder::{
379         BinderFeatures, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode,
380         Strong,
381     };
382     // Import from impl API for testing only, should not be necessary as long as
383     // you are using AIDL.
384     use binder::binder_impl::{Binder, IBinderInternal, TransactionCode};
385 
386     use binder_tokio::Tokio;
387 
388     use super::{BnTest, IATest, ITest, ITestSameDescriptor, TestService, RUST_SERVICE_BINARY};
389 
390     pub struct ScopedServiceProcess(Child);
391 
392     impl ScopedServiceProcess {
new(identifier: &str) -> Self393         pub fn new(identifier: &str) -> Self {
394             Self::new_internal(identifier, None)
395         }
396 
new_with_extension(identifier: &str, extension: &str) -> Self397         pub fn new_with_extension(identifier: &str, extension: &str) -> Self {
398             Self::new_internal(identifier, Some(extension))
399         }
400 
new_internal(identifier: &str, extension: Option<&str>) -> Self401         fn new_internal(identifier: &str, extension: Option<&str>) -> Self {
402             let mut binary_path =
403                 std::env::current_exe().expect("Could not retrieve current executable path");
404             binary_path.pop();
405             binary_path.push(RUST_SERVICE_BINARY);
406             let mut command = Command::new(&binary_path);
407             command.arg(identifier);
408             if let Some(ext) = extension {
409                 command.arg(ext);
410             }
411             let child = command.spawn().expect("Could not start service");
412             Self(child)
413         }
414     }
415 
416     impl Drop for ScopedServiceProcess {
drop(&mut self)417         fn drop(&mut self) {
418             self.0.kill().expect("Could not kill child process");
419             self.0.wait().expect("Could not wait for child process to die");
420         }
421     }
422 
423     #[test]
check_get_service()424     fn check_get_service() {
425         let mut sm = binder::get_service("manager").expect("Did not get manager binder service");
426         assert!(sm.is_binder_alive());
427         assert!(sm.ping_binder().is_ok());
428 
429         assert!(binder::get_service("this_service_does_not_exist").is_none());
430         assert_eq!(
431             binder::get_interface::<dyn ITest>("this_service_does_not_exist").err(),
432             Some(StatusCode::NAME_NOT_FOUND)
433         );
434         assert_eq!(
435             binder::get_interface::<dyn IATest<Tokio>>("this_service_does_not_exist").err(),
436             Some(StatusCode::NAME_NOT_FOUND)
437         );
438 
439         // The service manager service isn't an ITest, so this must fail.
440         assert_eq!(binder::get_interface::<dyn ITest>("manager").err(), Some(StatusCode::BAD_TYPE));
441         assert_eq!(
442             binder::get_interface::<dyn IATest<Tokio>>("manager").err(),
443             Some(StatusCode::BAD_TYPE)
444         );
445     }
446 
447     #[tokio::test]
check_get_service_async()448     async fn check_get_service_async() {
449         let mut sm = binder::get_service("manager").expect("Did not get manager binder service");
450         assert!(sm.is_binder_alive());
451         assert!(sm.ping_binder().is_ok());
452 
453         assert!(binder::get_service("this_service_does_not_exist").is_none());
454         assert_eq!(
455             binder_tokio::get_interface::<dyn ITest>("this_service_does_not_exist").await.err(),
456             Some(StatusCode::NAME_NOT_FOUND)
457         );
458         assert_eq!(
459             binder_tokio::get_interface::<dyn IATest<Tokio>>("this_service_does_not_exist")
460                 .await
461                 .err(),
462             Some(StatusCode::NAME_NOT_FOUND)
463         );
464 
465         // The service manager service isn't an ITest, so this must fail.
466         assert_eq!(
467             binder_tokio::get_interface::<dyn ITest>("manager").await.err(),
468             Some(StatusCode::BAD_TYPE)
469         );
470         assert_eq!(
471             binder_tokio::get_interface::<dyn IATest<Tokio>>("manager").await.err(),
472             Some(StatusCode::BAD_TYPE)
473         );
474     }
475 
476     #[test]
check_check_service()477     fn check_check_service() {
478         let mut sm = binder::check_service("manager").expect("Did not find manager binder service");
479         assert!(sm.is_binder_alive());
480         assert!(sm.ping_binder().is_ok());
481 
482         assert!(binder::check_service("this_service_does_not_exist").is_none());
483         assert_eq!(
484             binder::check_interface::<dyn ITest>("this_service_does_not_exist").err(),
485             Some(StatusCode::NAME_NOT_FOUND)
486         );
487         assert_eq!(
488             binder::check_interface::<dyn IATest<Tokio>>("this_service_does_not_exist").err(),
489             Some(StatusCode::NAME_NOT_FOUND)
490         );
491 
492         // The service manager service isn't an ITest, so this must fail.
493         assert_eq!(
494             binder::check_interface::<dyn ITest>("manager").err(),
495             Some(StatusCode::BAD_TYPE)
496         );
497         assert_eq!(
498             binder::check_interface::<dyn IATest<Tokio>>("manager").err(),
499             Some(StatusCode::BAD_TYPE)
500         );
501     }
502 
503     #[tokio::test]
check_check_service_async()504     async fn check_check_service_async() {
505         let mut sm = binder::check_service("manager").expect("Did not find manager binder service");
506         assert!(sm.is_binder_alive());
507         assert!(sm.ping_binder().is_ok());
508 
509         assert!(binder::check_service("this_service_does_not_exist").is_none());
510         assert_eq!(
511             binder_tokio::check_interface::<dyn ITest>("this_service_does_not_exist").await.err(),
512             Some(StatusCode::NAME_NOT_FOUND)
513         );
514         assert_eq!(
515             binder_tokio::check_interface::<dyn IATest<Tokio>>("this_service_does_not_exist")
516                 .await
517                 .err(),
518             Some(StatusCode::NAME_NOT_FOUND)
519         );
520 
521         // The service manager service isn't an ITest, so this must fail.
522         assert_eq!(
523             binder_tokio::check_interface::<dyn ITest>("manager").await.err(),
524             Some(StatusCode::BAD_TYPE)
525         );
526         assert_eq!(
527             binder_tokio::check_interface::<dyn IATest<Tokio>>("manager").await.err(),
528             Some(StatusCode::BAD_TYPE)
529         );
530     }
531 
532     #[test]
check_wait_for_service()533     fn check_wait_for_service() {
534         let mut sm =
535             binder::wait_for_service("manager").expect("Did not get manager binder service");
536         assert!(sm.is_binder_alive());
537         assert!(sm.ping_binder().is_ok());
538 
539         // The service manager service isn't an ITest, so this must fail.
540         assert_eq!(
541             binder::wait_for_interface::<dyn ITest>("manager").err(),
542             Some(StatusCode::BAD_TYPE)
543         );
544         assert_eq!(
545             binder::wait_for_interface::<dyn IATest<Tokio>>("manager").err(),
546             Some(StatusCode::BAD_TYPE)
547         );
548     }
549 
550     #[test]
get_declared_instances()551     fn get_declared_instances() {
552         // At the time of writing this test, there is no good VINTF interface
553         // guaranteed to be on all devices. Cuttlefish has light, so this will
554         // generally test things.
555         let has_lights = binder::is_declared("android.hardware.light.ILights/default")
556             .expect("Could not check for declared interface");
557 
558         let instances = binder::get_declared_instances("android.hardware.light.ILights")
559             .expect("Could not get declared instances");
560 
561         let expected_defaults = usize::from(has_lights);
562         assert_eq!(expected_defaults, instances.iter().filter(|i| i.as_str() == "default").count());
563     }
564 
565     #[test]
trivial_client()566     fn trivial_client() {
567         let service_name = "trivial_client_test";
568         let _process = ScopedServiceProcess::new(service_name);
569         let test_client: Strong<dyn ITest> =
570             binder::get_interface(service_name).expect("Did not get manager binder service");
571         assert_eq!(test_client.test().unwrap(), "trivial_client_test");
572     }
573 
574     #[tokio::test]
trivial_client_async()575     async fn trivial_client_async() {
576         let service_name = "trivial_client_test";
577         let _process = ScopedServiceProcess::new(service_name);
578         let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::get_interface(service_name)
579             .await
580             .expect("Did not get manager binder service");
581         assert_eq!(test_client.test().await.unwrap(), "trivial_client_test");
582     }
583 
584     #[test]
wait_for_trivial_client()585     fn wait_for_trivial_client() {
586         let service_name = "wait_for_trivial_client_test";
587         let _process = ScopedServiceProcess::new(service_name);
588         let test_client: Strong<dyn ITest> =
589             binder::wait_for_interface(service_name).expect("Did not get manager binder service");
590         assert_eq!(test_client.test().unwrap(), "wait_for_trivial_client_test");
591     }
592 
593     #[tokio::test]
wait_for_trivial_client_async()594     async fn wait_for_trivial_client_async() {
595         let service_name = "wait_for_trivial_client_test";
596         let _process = ScopedServiceProcess::new(service_name);
597         let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::wait_for_interface(service_name)
598             .await
599             .expect("Did not get manager binder service");
600         assert_eq!(test_client.test().await.unwrap(), "wait_for_trivial_client_test");
601     }
602 
get_expected_selinux_context() -> &'static str603     fn get_expected_selinux_context() -> &'static str {
604         // SAFETY: The pointer we pass to `getcon` is valid because it comes from a reference, and
605         // `getcon` doesn't retain it after it returns. If `getcon` succeeds then `out_ptr` will
606         // point to a valid C string, otherwise it will remain null. We check for null, so the
607         // pointer we pass to `CStr::from_ptr` must be a valid pointer to a C string. There is a
608         // memory leak as we don't call `freecon`, but that's fine because this is just a test.
609         unsafe {
610             let mut out_ptr = ptr::null_mut();
611             assert_eq!(selinux_sys::getcon(&mut out_ptr), 0);
612             assert!(!out_ptr.is_null());
613             CStr::from_ptr(out_ptr).to_str().expect("context was invalid UTF-8")
614         }
615     }
616 
617     #[test]
get_selinux_context()618     fn get_selinux_context() {
619         let service_name = "get_selinux_context";
620         let _process = ScopedServiceProcess::new(service_name);
621         let test_client: Strong<dyn ITest> =
622             binder::get_interface(service_name).expect("Did not get manager binder service");
623         assert_eq!(test_client.get_selinux_context().unwrap(), get_expected_selinux_context());
624     }
625 
626     #[tokio::test]
get_selinux_context_async()627     async fn get_selinux_context_async() {
628         let service_name = "get_selinux_context_async";
629         let _process = ScopedServiceProcess::new(service_name);
630         let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::get_interface(service_name)
631             .await
632             .expect("Did not get manager binder service");
633         assert_eq!(
634             test_client.get_selinux_context().await.unwrap(),
635             get_expected_selinux_context()
636         );
637     }
638 
639     #[tokio::test]
get_selinux_context_sync_to_async()640     async fn get_selinux_context_sync_to_async() {
641         let service_name = "get_selinux_context";
642         let _process = ScopedServiceProcess::new(service_name);
643         let test_client: Strong<dyn ITest> =
644             binder::get_interface(service_name).expect("Did not get manager binder service");
645         let test_client = test_client.into_async::<Tokio>();
646         assert_eq!(
647             test_client.get_selinux_context().await.unwrap(),
648             get_expected_selinux_context()
649         );
650     }
651 
652     #[tokio::test]
get_selinux_context_async_to_sync()653     async fn get_selinux_context_async_to_sync() {
654         let service_name = "get_selinux_context";
655         let _process = ScopedServiceProcess::new(service_name);
656         let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::get_interface(service_name)
657             .await
658             .expect("Did not get manager binder service");
659         let test_client = test_client.into_sync();
660         assert_eq!(test_client.get_selinux_context().unwrap(), get_expected_selinux_context());
661     }
662 
663     struct Bools {
664         binder_died: Arc<AtomicBool>,
665         binder_dealloc: Arc<AtomicBool>,
666     }
667 
668     impl Bools {
is_dead(&self) -> bool669         fn is_dead(&self) -> bool {
670             self.binder_died.load(Ordering::Relaxed)
671         }
assert_died(&self)672         fn assert_died(&self) {
673             assert!(self.is_dead(), "Did not receive death notification");
674         }
assert_dropped(&self)675         fn assert_dropped(&self) {
676             assert!(
677                 self.binder_dealloc.load(Ordering::Relaxed),
678                 "Did not dealloc death notification"
679             );
680         }
assert_not_dropped(&self)681         fn assert_not_dropped(&self) {
682             assert!(
683                 !self.binder_dealloc.load(Ordering::Relaxed),
684                 "Dealloc death notification too early"
685             );
686         }
687     }
688 
register_death_notification(binder: &mut SpIBinder) -> (Bools, DeathRecipient)689     fn register_death_notification(binder: &mut SpIBinder) -> (Bools, DeathRecipient) {
690         let binder_died = Arc::new(AtomicBool::new(false));
691         let binder_dealloc = Arc::new(AtomicBool::new(false));
692 
693         struct SetOnDrop {
694             binder_dealloc: Arc<AtomicBool>,
695         }
696         impl Drop for SetOnDrop {
697             fn drop(&mut self) {
698                 self.binder_dealloc.store(true, Ordering::Relaxed);
699             }
700         }
701 
702         let mut death_recipient = {
703             let flag = binder_died.clone();
704             let set_on_drop = SetOnDrop { binder_dealloc: binder_dealloc.clone() };
705             DeathRecipient::new(move || {
706                 flag.store(true, Ordering::Relaxed);
707                 // Force the closure to take ownership of set_on_drop. When the closure is
708                 // dropped, the destructor of `set_on_drop` will run.
709                 let _ = &set_on_drop;
710             })
711         };
712 
713         binder.link_to_death(&mut death_recipient).expect("link_to_death failed");
714 
715         let bools = Bools { binder_died, binder_dealloc };
716 
717         (bools, death_recipient)
718     }
719 
720     /// Killing a remote service should unregister the service and trigger
721     /// death notifications.
722     #[test]
test_death_notifications()723     fn test_death_notifications() {
724         binder::ProcessState::start_thread_pool();
725 
726         let service_name = "test_death_notifications";
727         let service_process = ScopedServiceProcess::new(service_name);
728         let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
729 
730         let (bools, recipient) = register_death_notification(&mut remote);
731 
732         drop(service_process);
733         remote.ping_binder().expect_err("Service should have died already");
734 
735         // Pause to ensure any death notifications get delivered
736         thread::sleep(Duration::from_secs(1));
737 
738         bools.assert_died();
739         bools.assert_not_dropped();
740 
741         drop(recipient);
742 
743         bools.assert_dropped();
744     }
745 
746     /// Test unregistering death notifications.
747     #[test]
test_unregister_death_notifications()748     fn test_unregister_death_notifications() {
749         binder::ProcessState::start_thread_pool();
750 
751         let service_name = "test_unregister_death_notifications";
752         let service_process = ScopedServiceProcess::new(service_name);
753         let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
754 
755         let (bools, mut recipient) = register_death_notification(&mut remote);
756 
757         remote.unlink_to_death(&mut recipient).expect("Could not unlink death notifications");
758 
759         drop(service_process);
760         remote.ping_binder().expect_err("Service should have died already");
761 
762         // Pause to ensure any death notifications get delivered
763         thread::sleep(Duration::from_secs(1));
764 
765         assert!(!bools.is_dead(), "Received unexpected death notification after unlinking",);
766 
767         bools.assert_not_dropped();
768         drop(recipient);
769         bools.assert_dropped();
770     }
771 
772     /// Dropping a remote handle should unregister any death notifications.
773     #[test]
test_death_notification_registration_lifetime()774     fn test_death_notification_registration_lifetime() {
775         binder::ProcessState::start_thread_pool();
776 
777         let service_name = "test_death_notification_registration_lifetime";
778         let service_process = ScopedServiceProcess::new(service_name);
779         let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
780 
781         let (bools, recipient) = register_death_notification(&mut remote);
782 
783         // This should automatically unregister our death notification.
784         drop(remote);
785 
786         drop(service_process);
787 
788         // Pause to ensure any death notifications get delivered
789         thread::sleep(Duration::from_secs(1));
790 
791         // We dropped the remote handle, so we should not receive the death
792         // notification when the remote process dies here.
793         assert!(
794             !bools.is_dead(),
795             "Received unexpected death notification after dropping remote handle"
796         );
797 
798         bools.assert_not_dropped();
799         drop(recipient);
800         bools.assert_dropped();
801     }
802 
803     /// Test IBinder interface methods not exercised elsewhere.
804     #[test]
test_misc_ibinder()805     fn test_misc_ibinder() {
806         let service_name = "rust_test_ibinder";
807 
808         {
809             let _process = ScopedServiceProcess::new(service_name);
810 
811             let test_client: Strong<dyn ITest> =
812                 binder::get_interface(service_name).expect("Did not get test binder service");
813             let mut remote = test_client.as_binder();
814             assert!(remote.is_binder_alive());
815             remote.ping_binder().expect("Could not ping remote service");
816 
817             let dump_args = ["dump", "args", "for", "testing"];
818 
819             let null_out = File::open("/dev/null").expect("Could not open /dev/null");
820             remote.dump(&null_out, &dump_args).expect("Could not dump remote service");
821 
822             let remote_args = test_client.get_dump_args().expect("Could not fetched dumped args");
823             assert_eq!(dump_args, remote_args[..], "Remote args don't match call to dump");
824         }
825 
826         // get/set_extensions is tested in test_extensions()
827 
828         // transact is tested everywhere else, and we can't make raw
829         // transactions outside the [FIRST_CALL_TRANSACTION,
830         // LAST_CALL_TRANSACTION] range from the NDK anyway.
831 
832         // link_to_death is tested in test_*_death_notification* tests.
833     }
834 
835     #[test]
test_extensions()836     fn test_extensions() {
837         let service_name = "rust_test_extensions";
838         let extension_name = "rust_test_extensions_ext";
839 
840         {
841             let _process = ScopedServiceProcess::new(service_name);
842 
843             let mut remote = binder::get_service(service_name);
844             assert!(remote.is_binder_alive());
845 
846             let extension = remote.get_extension().expect("Could not check for an extension");
847             assert!(extension.is_none());
848         }
849 
850         {
851             let _process = ScopedServiceProcess::new_with_extension(service_name, extension_name);
852 
853             let mut remote = binder::get_service(service_name);
854             assert!(remote.is_binder_alive());
855 
856             let maybe_extension = remote.get_extension().expect("Could not check for an extension");
857 
858             let extension = maybe_extension.expect("Remote binder did not have an extension");
859 
860             let extension: Strong<dyn ITest> = FromIBinder::try_from(extension)
861                 .expect("Extension could not be converted to the expected interface");
862 
863             assert_eq!(extension.test().unwrap(), extension_name);
864         }
865     }
866 
867     /// Test re-associating a local binder object with a different class.
868     ///
869     /// This is needed because different binder service (e.g. NDK vs Rust)
870     /// implementations are incompatible and must not be interchanged. A local
871     /// service with the same descriptor string but a different class pointer
872     /// may have been created by an NDK service and is therefore incompatible
873     /// with the Rust service implementation. It must be treated as remote and
874     /// all API calls parceled and sent through transactions.
875     ///
876     /// Further tests of this behavior with the C NDK and Rust API are in
877     /// rust_ndk_interop.rs
878     #[test]
associate_existing_class()879     fn associate_existing_class() {
880         let service = Binder::new(BnTest(Box::new(TestService::new("testing_service"))));
881 
882         // This should succeed although we will have to treat the service as
883         // remote.
884         let _interface: Strong<dyn ITestSameDescriptor> =
885             FromIBinder::try_from(service.as_binder())
886                 .expect("Could not re-interpret service as the ITestSameDescriptor interface");
887     }
888 
889     /// Test that we can round-trip a rust service through a generic IBinder
890     #[test]
reassociate_rust_binder()891     fn reassociate_rust_binder() {
892         let service_name = "testing_service";
893         let service_ibinder =
894             BnTest::new_binder(TestService::new(service_name), BinderFeatures::default())
895                 .as_binder();
896 
897         let service: Strong<dyn ITest> =
898             service_ibinder.into_interface().expect("Could not reassociate the generic ibinder");
899 
900         assert_eq!(service.test().unwrap(), service_name);
901     }
902 
903     #[test]
weak_binder_upgrade()904     fn weak_binder_upgrade() {
905         let service_name = "testing_service";
906         let service = BnTest::new_binder(TestService::new(service_name), BinderFeatures::default());
907 
908         let weak = Strong::downgrade(&service);
909 
910         let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
911 
912         assert_eq!(service, upgraded);
913     }
914 
915     #[test]
weak_binder_upgrade_dead()916     fn weak_binder_upgrade_dead() {
917         let service_name = "testing_service";
918         let weak = {
919             let service =
920                 BnTest::new_binder(TestService::new(service_name), BinderFeatures::default());
921 
922             Strong::downgrade(&service)
923         };
924 
925         assert_eq!(weak.upgrade(), Err(StatusCode::DEAD_OBJECT));
926     }
927 
928     #[test]
weak_binder_clone()929     fn weak_binder_clone() {
930         let service_name = "testing_service";
931         let service = BnTest::new_binder(TestService::new(service_name), BinderFeatures::default());
932 
933         let weak = Strong::downgrade(&service);
934         let cloned = weak.clone();
935         assert_eq!(weak, cloned);
936 
937         let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
938         let clone_upgraded = cloned.upgrade().expect("Could not upgrade weak binder");
939 
940         assert_eq!(service, upgraded);
941         assert_eq!(service, clone_upgraded);
942     }
943 
944     #[test]
945     #[allow(clippy::eq_op)]
binder_ord()946     fn binder_ord() {
947         let service1 =
948             BnTest::new_binder(TestService::new("testing_service1"), BinderFeatures::default());
949         let service2 =
950             BnTest::new_binder(TestService::new("testing_service2"), BinderFeatures::default());
951 
952         assert!((service1 >= service1));
953         assert!((service1 <= service1));
954         assert_eq!(service1 < service2, (service2 >= service1));
955     }
956 
957     #[test]
binder_parcel_mixup()958     fn binder_parcel_mixup() {
959         let service1 =
960             BnTest::new_binder(TestService::new("testing_service1"), BinderFeatures::default());
961         let service2 =
962             BnTest::new_binder(TestService::new("testing_service2"), BinderFeatures::default());
963 
964         let service1 = service1.as_binder();
965         let service2 = service2.as_binder();
966 
967         let parcel = service1.prepare_transact().unwrap();
968         let res = service2.submit_transact(
969             super::TestTransactionCode::Test as TransactionCode,
970             parcel,
971             0,
972         );
973 
974         match res {
975             Ok(_) => panic!("submit_transact should fail"),
976             Err(err) => assert_eq!(err, binder::StatusCode::BAD_VALUE),
977         }
978     }
979 
980     #[test]
get_is_handling_transaction()981     fn get_is_handling_transaction() {
982         let service_name = "get_is_handling_transaction";
983         let _process = ScopedServiceProcess::new(service_name);
984         let test_client: Strong<dyn ITest> =
985             binder::get_interface(service_name).expect("Did not get manager binder service");
986         // Should be true externally.
987         assert!(test_client.get_is_handling_transaction().unwrap());
988 
989         // Should be false locally.
990         assert!(!binder::is_handling_transaction());
991 
992         // Should also be false in spawned thread.
993         std::thread::spawn(|| {
994             assert!(!binder::is_handling_transaction());
995         })
996         .join()
997         .unwrap();
998     }
999 
1000     #[tokio::test]
get_is_handling_transaction_async()1001     async fn get_is_handling_transaction_async() {
1002         let service_name = "get_is_handling_transaction_async";
1003         let _process = ScopedServiceProcess::new(service_name);
1004         let test_client: Strong<dyn IATest<Tokio>> = binder_tokio::get_interface(service_name)
1005             .await
1006             .expect("Did not get manager binder service");
1007         // Should be true externally.
1008         assert!(test_client.get_is_handling_transaction().await.unwrap());
1009 
1010         // Should be false locally.
1011         assert!(!binder::is_handling_transaction());
1012 
1013         // Should also be false in spawned task.
1014         tokio::spawn(async {
1015             assert!(!binder::is_handling_transaction());
1016         })
1017         .await
1018         .unwrap();
1019 
1020         // And in spawn_blocking task.
1021         tokio::task::spawn_blocking(|| {
1022             assert!(!binder::is_handling_transaction());
1023         })
1024         .await
1025         .unwrap();
1026     }
1027 }
1028