blob: 09a956d2e9564a9b9a2cf59d12dde97bdf9bb3cd [file] [log] [blame]
Stephen Crane2a3c2502020-06-16 17:48:35 -07001/*
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
Stephen Crane7bca1052021-10-25 17:52:51 -070019use binder::{declare_binder_enum, declare_binder_interface};
Alice Ryhl8618c482021-11-09 15:35:35 +000020use binder::parcel::BorrowedParcel;
Andrew Walbran12400d82021-03-04 17:04:34 +000021use binder::{
Andrew Walbran88eca4f2021-04-13 14:26:01 +000022 Binder, BinderFeatures, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode,
Andrew Walbran12400d82021-03-04 17:04:34 +000023 FIRST_CALL_TRANSACTION,
24};
Janis Danisevskis798a09a2020-08-18 08:35:38 -070025use std::convert::{TryFrom, TryInto};
Stephen Crane2a3297f2021-06-11 16:48:10 -070026use std::ffi::CStr;
27use std::fs::File;
28use std::sync::Mutex;
Stephen Crane2a3c2502020-06-16 17:48:35 -070029
30/// Name of service runner.
31///
32/// Must match the binary name in Android.bp
33const RUST_SERVICE_BINARY: &str = "rustBinderTestService";
34
35/// Binary to run a test service.
36///
37/// This needs to be in a separate process from the tests, so we spawn this
38/// binary as a child, providing the service name as an argument.
39fn main() -> Result<(), &'static str> {
40 // Ensure that we can handle all transactions on the main thread.
41 binder::ProcessState::set_thread_pool_max_thread_count(0);
42 binder::ProcessState::start_thread_pool();
43
44 let mut args = std::env::args().skip(1);
45 if args.len() < 1 || args.len() > 2 {
46 print_usage();
47 return Err("");
48 }
49 let service_name = args.next().ok_or_else(|| {
50 print_usage();
51 "Missing SERVICE_NAME argument"
52 })?;
53 let extension_name = args.next();
54
55 {
Stephen Crane2a3297f2021-06-11 16:48:10 -070056 let mut service = Binder::new(BnTest(Box::new(TestService::new(&service_name))));
Janis Danisevskis798a09a2020-08-18 08:35:38 -070057 service.set_requesting_sid(true);
Stephen Crane2a3c2502020-06-16 17:48:35 -070058 if let Some(extension_name) = extension_name {
Andrew Walbran88eca4f2021-04-13 14:26:01 +000059 let extension =
Stephen Crane2a3297f2021-06-11 16:48:10 -070060 BnTest::new_binder(TestService::new(&extension_name), BinderFeatures::default());
Stephen Crane2a3c2502020-06-16 17:48:35 -070061 service
62 .set_extension(&mut extension.as_binder())
63 .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
73fn print_usage() {
74 eprintln!(
75 "Usage: {} SERVICE_NAME [EXTENSION_NAME]",
76 RUST_SERVICE_BINARY
77 );
78 eprintln!(concat!(
79 "Spawn a Binder test service identified by SERVICE_NAME,",
80 " optionally with an extesion named EXTENSION_NAME",
81 ));
82}
83
Stephen Crane2a3c2502020-06-16 17:48:35 -070084struct TestService {
85 s: String,
Stephen Crane2a3297f2021-06-11 16:48:10 -070086 dump_args: Mutex<Vec<String>>,
87}
88
89impl TestService {
90 fn new(s: &str) -> Self {
91 Self {
92 s: s.to_string(),
93 dump_args: Mutex::new(Vec::new()),
94 }
95 }
Stephen Crane2a3c2502020-06-16 17:48:35 -070096}
97
Janis Danisevskis798a09a2020-08-18 08:35:38 -070098#[repr(u32)]
99enum TestTransactionCode {
Andrew Walbran12400d82021-03-04 17:04:34 +0000100 Test = FIRST_CALL_TRANSACTION,
Stephen Crane2a3297f2021-06-11 16:48:10 -0700101 GetDumpArgs,
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700102 GetSelinuxContext,
Alice Ryhl29a50262021-12-10 11:14:32 +0000103 GetIsHandlingTransaction,
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700104}
105
106impl TryFrom<u32> for TestTransactionCode {
107 type Error = StatusCode;
108
109 fn try_from(c: u32) -> Result<Self, Self::Error> {
110 match c {
111 _ if c == TestTransactionCode::Test as u32 => Ok(TestTransactionCode::Test),
Stephen Crane2a3297f2021-06-11 16:48:10 -0700112 _ if c == TestTransactionCode::GetDumpArgs as u32 => Ok(TestTransactionCode::GetDumpArgs),
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700113 _ if c == TestTransactionCode::GetSelinuxContext as u32 => {
114 Ok(TestTransactionCode::GetSelinuxContext)
115 }
Alice Ryhl29a50262021-12-10 11:14:32 +0000116 _ if c == TestTransactionCode::GetIsHandlingTransaction as u32 => Ok(TestTransactionCode::GetIsHandlingTransaction),
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700117 _ => Err(StatusCode::UNKNOWN_TRANSACTION),
118 }
119 }
120}
121
Stephen Crane2a3297f2021-06-11 16:48:10 -0700122impl Interface for TestService {
123 fn dump(&self, _file: &File, args: &[&CStr]) -> binder::Result<()> {
124 let mut dump_args = self.dump_args.lock().unwrap();
125 dump_args.extend(args.iter().map(|s| s.to_str().unwrap().to_owned()));
126 Ok(())
127 }
128}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700129
130impl ITest for TestService {
131 fn test(&self) -> binder::Result<String> {
132 Ok(self.s.clone())
133 }
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700134
Stephen Crane2a3297f2021-06-11 16:48:10 -0700135 fn get_dump_args(&self) -> binder::Result<Vec<String>> {
136 let args = self.dump_args.lock().unwrap().clone();
137 Ok(args)
138 }
139
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700140 fn get_selinux_context(&self) -> binder::Result<String> {
141 let sid =
142 ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned()));
143 sid.ok_or(StatusCode::UNEXPECTED_NULL)
144 }
Alice Ryhl29a50262021-12-10 11:14:32 +0000145
146 fn get_is_handling_transaction(&self) -> binder::Result<bool> {
147 Ok(binder::is_handling_transaction())
148 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700149}
150
151/// Trivial testing binder interface
152pub trait ITest: Interface {
153 /// Returns a test string
154 fn test(&self) -> binder::Result<String>;
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700155
Stephen Crane2a3297f2021-06-11 16:48:10 -0700156 /// Return the arguments sent via dump
157 fn get_dump_args(&self) -> binder::Result<Vec<String>>;
158
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700159 /// Returns the caller's SELinux context
160 fn get_selinux_context(&self) -> binder::Result<String>;
Alice Ryhl29a50262021-12-10 11:14:32 +0000161
162 /// Returns the value of calling `is_handling_transaction`.
163 fn get_is_handling_transaction(&self) -> binder::Result<bool>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700164}
165
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000166/// Async trivial testing binder interface
167pub trait IATest<P>: Interface {
168 /// Returns a test string
169 fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>>;
170
171 /// Return the arguments sent via dump
172 fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>>;
173
174 /// Returns the caller's SELinux context
175 fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>>;
Alice Ryhl29a50262021-12-10 11:14:32 +0000176
177 /// Returns the value of calling `is_handling_transaction`.
178 fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>>;
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000179}
180
Stephen Crane2a3c2502020-06-16 17:48:35 -0700181declare_binder_interface! {
182 ITest["android.os.ITest"] {
183 native: BnTest(on_transact),
184 proxy: BpTest {
185 x: i32 = 100
186 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000187 async: IATest,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700188 }
189}
190
191fn on_transact(
192 service: &dyn ITest,
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700193 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000194 _data: &BorrowedParcel<'_>,
195 reply: &mut BorrowedParcel<'_>,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700196) -> binder::Result<()> {
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700197 match code.try_into()? {
198 TestTransactionCode::Test => reply.write(&service.test()?),
Stephen Crane2a3297f2021-06-11 16:48:10 -0700199 TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?),
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700200 TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?),
Alice Ryhl29a50262021-12-10 11:14:32 +0000201 TestTransactionCode::GetIsHandlingTransaction => reply.write(&service.get_is_handling_transaction()?),
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700202 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700203}
204
205impl ITest for BpTest {
206 fn test(&self) -> binder::Result<String> {
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700207 let reply =
208 self.binder
209 .transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(()))?;
210 reply.read()
211 }
212
Stephen Crane2a3297f2021-06-11 16:48:10 -0700213 fn get_dump_args(&self) -> binder::Result<Vec<String>> {
214 let reply =
215 self.binder
216 .transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(()))?;
217 reply.read()
218 }
219
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700220 fn get_selinux_context(&self) -> binder::Result<String> {
221 let reply = self.binder.transact(
222 TestTransactionCode::GetSelinuxContext as TransactionCode,
223 0,
224 |_| Ok(()),
225 )?;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700226 reply.read()
227 }
Alice Ryhl29a50262021-12-10 11:14:32 +0000228
229 fn get_is_handling_transaction(&self) -> binder::Result<bool> {
230 let reply = self.binder.transact(
231 TestTransactionCode::GetIsHandlingTransaction as TransactionCode,
232 0,
233 |_| Ok(()),
234 )?;
235 reply.read()
236 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700237}
238
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000239impl<P: binder::BinderAsyncPool> IATest<P> for BpTest {
240 fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
241 let binder = self.binder.clone();
242 P::spawn(
Alice Ryhl8618c482021-11-09 15:35:35 +0000243 move || binder.transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(())),
244 |reply| async move { reply?.read() }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000245 )
246 }
247
248 fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>> {
249 let binder = self.binder.clone();
250 P::spawn(
Alice Ryhl8618c482021-11-09 15:35:35 +0000251 move || binder.transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(())),
252 |reply| async move { reply?.read() }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000253 )
254 }
255
256 fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
257 let binder = self.binder.clone();
258 P::spawn(
Alice Ryhl8618c482021-11-09 15:35:35 +0000259 move || binder.transact(TestTransactionCode::GetSelinuxContext as TransactionCode, 0, |_| Ok(())),
260 |reply| async move { reply?.read() }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000261 )
262 }
Alice Ryhl29a50262021-12-10 11:14:32 +0000263
264 fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>> {
265 let binder = self.binder.clone();
266 P::spawn(
267 move || binder.transact(TestTransactionCode::GetIsHandlingTransaction as TransactionCode, 0, |_| Ok(())),
268 |reply| async move { reply?.read() }
269 )
270 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000271}
272
Stephen Crane2a3c2502020-06-16 17:48:35 -0700273impl ITest for Binder<BnTest> {
274 fn test(&self) -> binder::Result<String> {
275 self.0.test()
276 }
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700277
Stephen Crane2a3297f2021-06-11 16:48:10 -0700278 fn get_dump_args(&self) -> binder::Result<Vec<String>> {
279 self.0.get_dump_args()
280 }
281
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700282 fn get_selinux_context(&self) -> binder::Result<String> {
283 self.0.get_selinux_context()
284 }
Alice Ryhl29a50262021-12-10 11:14:32 +0000285
286 fn get_is_handling_transaction(&self) -> binder::Result<bool> {
287 self.0.get_is_handling_transaction()
288 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700289}
290
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000291impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> {
292 fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
293 let res = self.0.test();
294 Box::pin(async move { res })
295 }
296
297 fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>> {
298 let res = self.0.get_dump_args();
299 Box::pin(async move { res })
300 }
301
302 fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
303 let res = self.0.get_selinux_context();
304 Box::pin(async move { res })
305 }
Alice Ryhl29a50262021-12-10 11:14:32 +0000306
307 fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>> {
308 let res = self.0.get_is_handling_transaction();
309 Box::pin(async move { res })
310 }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000311}
312
Stephen Crane669deb62020-09-10 17:31:39 -0700313/// Trivial testing binder interface
314pub trait ITestSameDescriptor: Interface {}
315
316declare_binder_interface! {
317 ITestSameDescriptor["android.os.ITest"] {
318 native: BnTestSameDescriptor(on_transact_same_descriptor),
319 proxy: BpTestSameDescriptor,
320 }
321}
322
323fn on_transact_same_descriptor(
324 _service: &dyn ITestSameDescriptor,
325 _code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000326 _data: &BorrowedParcel<'_>,
327 _reply: &mut BorrowedParcel<'_>,
Stephen Crane669deb62020-09-10 17:31:39 -0700328) -> binder::Result<()> {
329 Ok(())
330}
331
332impl ITestSameDescriptor for BpTestSameDescriptor {}
333
334impl ITestSameDescriptor for Binder<BnTestSameDescriptor> {}
335
Stephen Crane7bca1052021-10-25 17:52:51 -0700336declare_binder_enum! {
337 TestEnum : [i32; 3] {
338 FOO = 1,
339 BAR = 2,
340 BAZ = 3,
341 }
342}
343
344declare_binder_enum! {
345 #[deprecated(since = "1.0.0")]
346 TestDeprecatedEnum : [i32; 3] {
347 FOO = 1,
348 BAR = 2,
349 BAZ = 3,
350 }
351}
352
Stephen Crane2a3c2502020-06-16 17:48:35 -0700353#[cfg(test)]
354mod tests {
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700355 use selinux_bindgen as selinux_sys;
356 use std::ffi::CStr;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700357 use std::fs::File;
358 use std::process::{Child, Command};
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700359 use std::ptr;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700360 use std::sync::atomic::{AtomicBool, Ordering};
361 use std::sync::Arc;
362 use std::thread;
363 use std::time::Duration;
364
Andrew Walbran12400d82021-03-04 17:04:34 +0000365 use binder::{
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000366 Binder, BinderFeatures, DeathRecipient, FromIBinder, IBinder, IBinderInternal, Interface,
367 SpIBinder, StatusCode, Strong,
Andrew Walbran12400d82021-03-04 17:04:34 +0000368 };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700369
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000370 use binder_tokio::Tokio;
371
372 use super::{BnTest, ITest, IATest, ITestSameDescriptor, TestService, RUST_SERVICE_BINARY};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700373
374 pub struct ScopedServiceProcess(Child);
375
376 impl ScopedServiceProcess {
377 pub fn new(identifier: &str) -> Self {
378 Self::new_internal(identifier, None)
379 }
380
381 pub fn new_with_extension(identifier: &str, extension: &str) -> Self {
382 Self::new_internal(identifier, Some(extension))
383 }
384
385 fn new_internal(identifier: &str, extension: Option<&str>) -> Self {
386 let mut binary_path =
387 std::env::current_exe().expect("Could not retrieve current executable path");
388 binary_path.pop();
389 binary_path.push(RUST_SERVICE_BINARY);
390 let mut command = Command::new(&binary_path);
391 command.arg(identifier);
392 if let Some(ext) = extension {
393 command.arg(ext);
394 }
395 let child = command.spawn().expect("Could not start service");
396 Self(child)
397 }
398 }
399
400 impl Drop for ScopedServiceProcess {
401 fn drop(&mut self) {
402 self.0.kill().expect("Could not kill child process");
403 self.0
404 .wait()
405 .expect("Could not wait for child process to die");
406 }
407 }
408
409 #[test]
410 fn check_services() {
411 let mut sm = binder::get_service("manager").expect("Did not get manager binder service");
412 assert!(sm.is_binder_alive());
413 assert!(sm.ping_binder().is_ok());
414
415 assert!(binder::get_service("this_service_does_not_exist").is_none());
416 assert_eq!(
417 binder::get_interface::<dyn ITest>("this_service_does_not_exist").err(),
418 Some(StatusCode::NAME_NOT_FOUND)
419 );
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000420 assert_eq!(
421 binder::get_interface::<dyn IATest<Tokio>>("this_service_does_not_exist").err(),
422 Some(StatusCode::NAME_NOT_FOUND)
423 );
Stephen Crane2a3c2502020-06-16 17:48:35 -0700424
425 // The service manager service isn't an ITest, so this must fail.
426 assert_eq!(
427 binder::get_interface::<dyn ITest>("manager").err(),
428 Some(StatusCode::BAD_TYPE)
429 );
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000430 assert_eq!(
431 binder::get_interface::<dyn IATest<Tokio>>("manager").err(),
432 Some(StatusCode::BAD_TYPE)
433 );
Stephen Crane2a3c2502020-06-16 17:48:35 -0700434 }
435
Alice Ryhl929804f2021-11-02 12:04:39 +0000436 #[tokio::test]
437 async fn check_services_async() {
438 let mut sm = binder::get_service("manager").expect("Did not get manager binder service");
439 assert!(sm.is_binder_alive());
440 assert!(sm.ping_binder().is_ok());
441
442 assert!(binder::get_service("this_service_does_not_exist").is_none());
443 assert_eq!(
444 binder_tokio::get_interface::<dyn ITest>("this_service_does_not_exist").await.err(),
445 Some(StatusCode::NAME_NOT_FOUND)
446 );
447 assert_eq!(
448 binder_tokio::get_interface::<dyn IATest<Tokio>>("this_service_does_not_exist").await.err(),
449 Some(StatusCode::NAME_NOT_FOUND)
450 );
451
452 // The service manager service isn't an ITest, so this must fail.
453 assert_eq!(
454 binder_tokio::get_interface::<dyn ITest>("manager").await.err(),
455 Some(StatusCode::BAD_TYPE)
456 );
457 assert_eq!(
458 binder_tokio::get_interface::<dyn IATest<Tokio>>("manager").await.err(),
459 Some(StatusCode::BAD_TYPE)
460 );
461 }
462
Stephen Crane2a3c2502020-06-16 17:48:35 -0700463 #[test]
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000464 fn check_wait_for_service() {
465 let mut sm =
466 binder::wait_for_service("manager").expect("Did not get manager binder service");
467 assert!(sm.is_binder_alive());
468 assert!(sm.ping_binder().is_ok());
469
470 // The service manager service isn't an ITest, so this must fail.
471 assert_eq!(
472 binder::wait_for_interface::<dyn ITest>("manager").err(),
473 Some(StatusCode::BAD_TYPE)
474 );
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000475 assert_eq!(
476 binder::wait_for_interface::<dyn IATest<Tokio>>("manager").err(),
477 Some(StatusCode::BAD_TYPE)
478 );
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000479 }
480
481 #[test]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700482 fn trivial_client() {
483 let service_name = "trivial_client_test";
484 let _process = ScopedServiceProcess::new(service_name);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800485 let test_client: Strong<dyn ITest> =
Stephen Crane2a3c2502020-06-16 17:48:35 -0700486 binder::get_interface(service_name).expect("Did not get manager binder service");
487 assert_eq!(test_client.test().unwrap(), "trivial_client_test");
488 }
489
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000490 #[tokio::test]
491 async fn trivial_client_async() {
492 let service_name = "trivial_client_test";
493 let _process = ScopedServiceProcess::new(service_name);
494 let test_client: Strong<dyn IATest<Tokio>> =
Alice Ryhl929804f2021-11-02 12:04:39 +0000495 binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service");
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000496 assert_eq!(test_client.test().await.unwrap(), "trivial_client_test");
497 }
498
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700499 #[test]
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000500 fn wait_for_trivial_client() {
501 let service_name = "wait_for_trivial_client_test";
502 let _process = ScopedServiceProcess::new(service_name);
503 let test_client: Strong<dyn ITest> =
504 binder::wait_for_interface(service_name).expect("Did not get manager binder service");
505 assert_eq!(test_client.test().unwrap(), "wait_for_trivial_client_test");
506 }
507
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000508 #[tokio::test]
509 async fn wait_for_trivial_client_async() {
510 let service_name = "wait_for_trivial_client_test";
511 let _process = ScopedServiceProcess::new(service_name);
512 let test_client: Strong<dyn IATest<Tokio>> =
Alice Ryhl929804f2021-11-02 12:04:39 +0000513 binder_tokio::wait_for_interface(service_name).await.expect("Did not get manager binder service");
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000514 assert_eq!(test_client.test().await.unwrap(), "wait_for_trivial_client_test");
515 }
516
517 fn get_expected_selinux_context() -> &'static str {
518 unsafe {
519 let mut out_ptr = ptr::null_mut();
520 assert_eq!(selinux_sys::getcon(&mut out_ptr), 0);
521 assert!(!out_ptr.is_null());
522 CStr::from_ptr(out_ptr)
523 .to_str()
524 .expect("context was invalid UTF-8")
525 }
526 }
527
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000528 #[test]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700529 fn get_selinux_context() {
530 let service_name = "get_selinux_context";
531 let _process = ScopedServiceProcess::new(service_name);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800532 let test_client: Strong<dyn ITest> =
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700533 binder::get_interface(service_name).expect("Did not get manager binder service");
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700534 assert_eq!(
535 test_client.get_selinux_context().unwrap(),
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000536 get_expected_selinux_context()
537 );
538 }
539
540 #[tokio::test]
541 async fn get_selinux_context_async() {
Alice Ryhl29a50262021-12-10 11:14:32 +0000542 let service_name = "get_selinux_context_async";
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000543 let _process = ScopedServiceProcess::new(service_name);
544 let test_client: Strong<dyn IATest<Tokio>> =
Alice Ryhl929804f2021-11-02 12:04:39 +0000545 binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service");
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000546 assert_eq!(
547 test_client.get_selinux_context().await.unwrap(),
548 get_expected_selinux_context()
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700549 );
550 }
551
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000552 struct Bools {
553 binder_died: Arc<AtomicBool>,
554 binder_dealloc: Arc<AtomicBool>,
555 }
556
557 impl Bools {
558 fn is_dead(&self) -> bool {
559 self.binder_died.load(Ordering::Relaxed)
560 }
561 fn assert_died(&self) {
562 assert!(
563 self.is_dead(),
564 "Did not receive death notification"
565 );
566 }
567 fn assert_dropped(&self) {
568 assert!(
569 self.binder_dealloc.load(Ordering::Relaxed),
570 "Did not dealloc death notification"
571 );
572 }
573 fn assert_not_dropped(&self) {
574 assert!(
575 !self.binder_dealloc.load(Ordering::Relaxed),
576 "Dealloc death notification too early"
577 );
578 }
579 }
580
581 fn register_death_notification(binder: &mut SpIBinder) -> (Bools, DeathRecipient) {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700582 let binder_died = Arc::new(AtomicBool::new(false));
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000583 let binder_dealloc = Arc::new(AtomicBool::new(false));
584
585 struct SetOnDrop {
586 binder_dealloc: Arc<AtomicBool>,
587 }
588 impl Drop for SetOnDrop {
589 fn drop(&mut self) {
590 self.binder_dealloc.store(true, Ordering::Relaxed);
591 }
592 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700593
594 let mut death_recipient = {
595 let flag = binder_died.clone();
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000596 let set_on_drop = SetOnDrop {
597 binder_dealloc: binder_dealloc.clone(),
598 };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700599 DeathRecipient::new(move || {
600 flag.store(true, Ordering::Relaxed);
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000601 // Force the closure to take ownership of set_on_drop. When the closure is
602 // dropped, the destructor of `set_on_drop` will run.
603 let _ = &set_on_drop;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700604 })
605 };
606
607 binder
608 .link_to_death(&mut death_recipient)
609 .expect("link_to_death failed");
610
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000611 let bools = Bools {
612 binder_died,
613 binder_dealloc,
614 };
615
616 (bools, death_recipient)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700617 }
618
619 /// Killing a remote service should unregister the service and trigger
620 /// death notifications.
621 #[test]
622 fn test_death_notifications() {
623 binder::ProcessState::start_thread_pool();
624
625 let service_name = "test_death_notifications";
626 let service_process = ScopedServiceProcess::new(service_name);
627 let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
628
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000629 let (bools, recipient) = register_death_notification(&mut remote);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700630
631 drop(service_process);
632 remote
633 .ping_binder()
634 .expect_err("Service should have died already");
635
636 // Pause to ensure any death notifications get delivered
637 thread::sleep(Duration::from_secs(1));
638
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000639 bools.assert_died();
640 bools.assert_not_dropped();
641
642 drop(recipient);
643
644 bools.assert_dropped();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700645 }
646
647 /// Test unregistering death notifications.
648 #[test]
649 fn test_unregister_death_notifications() {
650 binder::ProcessState::start_thread_pool();
651
652 let service_name = "test_unregister_death_notifications";
653 let service_process = ScopedServiceProcess::new(service_name);
654 let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
655
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000656 let (bools, mut recipient) = register_death_notification(&mut remote);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700657
658 remote
659 .unlink_to_death(&mut recipient)
660 .expect("Could not unlink death notifications");
661
662 drop(service_process);
663 remote
664 .ping_binder()
665 .expect_err("Service should have died already");
666
667 // Pause to ensure any death notifications get delivered
668 thread::sleep(Duration::from_secs(1));
669
670 assert!(
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000671 !bools.is_dead(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700672 "Received unexpected death notification after unlinking",
673 );
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000674
675 bools.assert_not_dropped();
676 drop(recipient);
677 bools.assert_dropped();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700678 }
679
680 /// Dropping a remote handle should unregister any death notifications.
681 #[test]
682 fn test_death_notification_registration_lifetime() {
683 binder::ProcessState::start_thread_pool();
684
685 let service_name = "test_death_notification_registration_lifetime";
686 let service_process = ScopedServiceProcess::new(service_name);
687 let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
688
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000689 let (bools, recipient) = register_death_notification(&mut remote);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700690
691 // This should automatically unregister our death notification.
692 drop(remote);
693
694 drop(service_process);
695
696 // Pause to ensure any death notifications get delivered
697 thread::sleep(Duration::from_secs(1));
698
699 // We dropped the remote handle, so we should not receive the death
700 // notification when the remote process dies here.
701 assert!(
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000702 !bools.is_dead(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700703 "Received unexpected death notification after dropping remote handle"
704 );
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000705
706 bools.assert_not_dropped();
707 drop(recipient);
708 bools.assert_dropped();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700709 }
710
711 /// Test IBinder interface methods not exercised elsewhere.
712 #[test]
713 fn test_misc_ibinder() {
714 let service_name = "rust_test_ibinder";
715
716 {
717 let _process = ScopedServiceProcess::new(service_name);
718
Stephen Crane2a3297f2021-06-11 16:48:10 -0700719 let test_client: Strong<dyn ITest> =
720 binder::get_interface(service_name)
721 .expect("Did not get test binder service");
722 let mut remote = test_client.as_binder();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700723 assert!(remote.is_binder_alive());
724 remote.ping_binder().expect("Could not ping remote service");
725
Stephen Crane2a3297f2021-06-11 16:48:10 -0700726 let dump_args = ["dump", "args", "for", "testing"];
727
Stephen Crane2a3c2502020-06-16 17:48:35 -0700728 let null_out = File::open("/dev/null").expect("Could not open /dev/null");
729 remote
Stephen Crane2a3297f2021-06-11 16:48:10 -0700730 .dump(&null_out, &dump_args)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700731 .expect("Could not dump remote service");
Stephen Crane2a3297f2021-06-11 16:48:10 -0700732
733 let remote_args = test_client.get_dump_args().expect("Could not fetched dumped args");
734 assert_eq!(dump_args, remote_args[..], "Remote args don't match call to dump");
Stephen Crane2a3c2502020-06-16 17:48:35 -0700735 }
736
737 // get/set_extensions is tested in test_extensions()
738
739 // transact is tested everywhere else, and we can't make raw
740 // transactions outside the [FIRST_CALL_TRANSACTION,
741 // LAST_CALL_TRANSACTION] range from the NDK anyway.
742
743 // link_to_death is tested in test_*_death_notification* tests.
744 }
745
746 #[test]
747 fn test_extensions() {
748 let service_name = "rust_test_extensions";
749 let extension_name = "rust_test_extensions_ext";
750
751 {
752 let _process = ScopedServiceProcess::new(service_name);
753
754 let mut remote = binder::get_service(service_name);
755 assert!(remote.is_binder_alive());
756
757 let extension = remote
758 .get_extension()
759 .expect("Could not check for an extension");
760 assert!(extension.is_none());
761 }
762
763 {
764 let _process = ScopedServiceProcess::new_with_extension(service_name, extension_name);
765
766 let mut remote = binder::get_service(service_name);
767 assert!(remote.is_binder_alive());
768
769 let maybe_extension = remote
770 .get_extension()
771 .expect("Could not check for an extension");
772
773 let extension = maybe_extension.expect("Remote binder did not have an extension");
774
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800775 let extension: Strong<dyn ITest> = FromIBinder::try_from(extension)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700776 .expect("Extension could not be converted to the expected interface");
777
778 assert_eq!(extension.test().unwrap(), extension_name);
779 }
780 }
Stephen Crane669deb62020-09-10 17:31:39 -0700781
782 /// Test re-associating a local binder object with a different class.
783 ///
784 /// This is needed because different binder service (e.g. NDK vs Rust)
785 /// implementations are incompatible and must not be interchanged. A local
786 /// service with the same descriptor string but a different class pointer
787 /// may have been created by an NDK service and is therefore incompatible
788 /// with the Rust service implementation. It must be treated as remote and
789 /// all API calls parceled and sent through transactions.
790 ///
791 /// Further tests of this behavior with the C NDK and Rust API are in
792 /// rust_ndk_interop.rs
793 #[test]
794 fn associate_existing_class() {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700795 let service = Binder::new(BnTest(Box::new(TestService::new("testing_service"))));
Stephen Crane669deb62020-09-10 17:31:39 -0700796
797 // This should succeed although we will have to treat the service as
798 // remote.
Andrew Walbran12400d82021-03-04 17:04:34 +0000799 let _interface: Strong<dyn ITestSameDescriptor> =
800 FromIBinder::try_from(service.as_binder())
801 .expect("Could not re-interpret service as the ITestSameDescriptor interface");
Stephen Crane669deb62020-09-10 17:31:39 -0700802 }
803
804 /// Test that we can round-trip a rust service through a generic IBinder
805 #[test]
806 fn reassociate_rust_binder() {
807 let service_name = "testing_service";
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000808 let service_ibinder = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700809 TestService::new(service_name),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000810 BinderFeatures::default(),
811 )
Andrew Walbran12400d82021-03-04 17:04:34 +0000812 .as_binder();
Stephen Crane669deb62020-09-10 17:31:39 -0700813
Andrew Walbran12400d82021-03-04 17:04:34 +0000814 let service: Strong<dyn ITest> = service_ibinder
815 .into_interface()
Stephen Crane669deb62020-09-10 17:31:39 -0700816 .expect("Could not reassociate the generic ibinder");
817
818 assert_eq!(service.test().unwrap(), service_name);
819 }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800820
821 #[test]
822 fn weak_binder_upgrade() {
823 let service_name = "testing_service";
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000824 let service = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700825 TestService::new(service_name),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000826 BinderFeatures::default(),
827 );
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800828
829 let weak = Strong::downgrade(&service);
830
831 let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
832
833 assert_eq!(service, upgraded);
834 }
835
836 #[test]
837 fn weak_binder_upgrade_dead() {
838 let service_name = "testing_service";
839 let weak = {
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000840 let service = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700841 TestService::new(service_name),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000842 BinderFeatures::default(),
843 );
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800844
845 Strong::downgrade(&service)
846 };
847
848 assert_eq!(weak.upgrade(), Err(StatusCode::DEAD_OBJECT));
849 }
850
851 #[test]
852 fn weak_binder_clone() {
853 let service_name = "testing_service";
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000854 let service = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700855 TestService::new(service_name),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000856 BinderFeatures::default(),
857 );
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800858
859 let weak = Strong::downgrade(&service);
860 let cloned = weak.clone();
861 assert_eq!(weak, cloned);
862
863 let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
864 let clone_upgraded = cloned.upgrade().expect("Could not upgrade weak binder");
865
866 assert_eq!(service, upgraded);
867 assert_eq!(service, clone_upgraded);
868 }
869
870 #[test]
871 #[allow(clippy::eq_op)]
872 fn binder_ord() {
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000873 let service1 = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700874 TestService::new("testing_service1"),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000875 BinderFeatures::default(),
876 );
877 let service2 = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700878 TestService::new("testing_service2"),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000879 BinderFeatures::default(),
880 );
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800881
882 assert!(!(service1 < service1));
883 assert!(!(service1 > service1));
884 assert_eq!(service1 < service2, !(service2 < service1));
885 }
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000886
887 #[test]
888 fn binder_parcel_mixup() {
889 let service1 = BnTest::new_binder(
890 TestService::new("testing_service1"),
891 BinderFeatures::default(),
892 );
893 let service2 = BnTest::new_binder(
894 TestService::new("testing_service2"),
895 BinderFeatures::default(),
896 );
897
898 let service1 = service1.as_binder();
899 let service2 = service2.as_binder();
900
901 let parcel = service1.prepare_transact().unwrap();
902 let res = service2.submit_transact(super::TestTransactionCode::Test as binder::TransactionCode, parcel, 0);
903
904 match res {
905 Ok(_) => panic!("submit_transact should fail"),
906 Err(err) => assert_eq!(err, binder::StatusCode::BAD_VALUE),
907 }
908 }
Alice Ryhl29a50262021-12-10 11:14:32 +0000909
910 #[test]
911 fn get_is_handling_transaction() {
912 let service_name = "get_is_handling_transaction";
913 let _process = ScopedServiceProcess::new(service_name);
914 let test_client: Strong<dyn ITest> =
915 binder::get_interface(service_name).expect("Did not get manager binder service");
916 // Should be true externally.
917 assert!(test_client.get_is_handling_transaction().unwrap());
918
919 // Should be false locally.
920 assert!(!binder::is_handling_transaction());
921
922 // Should also be false in spawned thread.
923 std::thread::spawn(|| {
924 assert!(!binder::is_handling_transaction());
925 }).join().unwrap();
926 }
927
928 #[tokio::test]
929 async fn get_is_handling_transaction_async() {
930 let service_name = "get_is_handling_transaction_async";
931 let _process = ScopedServiceProcess::new(service_name);
932 let test_client: Strong<dyn IATest<Tokio>> =
933 binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service");
934 // Should be true externally.
935 assert!(test_client.get_is_handling_transaction().await.unwrap());
936
937 // Should be false locally.
938 assert!(!binder::is_handling_transaction());
939
940 // Should also be false in spawned task.
941 tokio::spawn(async {
942 assert!(!binder::is_handling_transaction());
943 }).await.unwrap();
944
945 // And in spawn_blocking task.
946 tokio::task::spawn_blocking(|| {
947 assert!(!binder::is_handling_transaction());
948 }).await.unwrap();
949 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700950}