blob: 40359b4749552cf46aa0fb75c4030456c6229a5a [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,
103}
104
105impl TryFrom<u32> for TestTransactionCode {
106 type Error = StatusCode;
107
108 fn try_from(c: u32) -> Result<Self, Self::Error> {
109 match c {
110 _ if c == TestTransactionCode::Test as u32 => Ok(TestTransactionCode::Test),
Stephen Crane2a3297f2021-06-11 16:48:10 -0700111 _ if c == TestTransactionCode::GetDumpArgs as u32 => Ok(TestTransactionCode::GetDumpArgs),
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700112 _ if c == TestTransactionCode::GetSelinuxContext as u32 => {
113 Ok(TestTransactionCode::GetSelinuxContext)
114 }
115 _ => Err(StatusCode::UNKNOWN_TRANSACTION),
116 }
117 }
118}
119
Stephen Crane2a3297f2021-06-11 16:48:10 -0700120impl Interface for TestService {
121 fn dump(&self, _file: &File, args: &[&CStr]) -> binder::Result<()> {
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}
Stephen Crane2a3c2502020-06-16 17:48:35 -0700127
128impl ITest for TestService {
129 fn test(&self) -> binder::Result<String> {
130 Ok(self.s.clone())
131 }
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700132
Stephen Crane2a3297f2021-06-11 16:48:10 -0700133 fn get_dump_args(&self) -> binder::Result<Vec<String>> {
134 let args = self.dump_args.lock().unwrap().clone();
135 Ok(args)
136 }
137
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700138 fn get_selinux_context(&self) -> binder::Result<String> {
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 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700143}
144
145/// Trivial testing binder interface
146pub trait ITest: Interface {
147 /// Returns a test string
148 fn test(&self) -> binder::Result<String>;
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700149
Stephen Crane2a3297f2021-06-11 16:48:10 -0700150 /// Return the arguments sent via dump
151 fn get_dump_args(&self) -> binder::Result<Vec<String>>;
152
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700153 /// Returns the caller's SELinux context
154 fn get_selinux_context(&self) -> binder::Result<String>;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700155}
156
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000157/// Async trivial testing binder interface
158pub trait IATest<P>: Interface {
159 /// Returns a test string
160 fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>>;
161
162 /// Return the arguments sent via dump
163 fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>>;
164
165 /// Returns the caller's SELinux context
166 fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>>;
167}
168
Stephen Crane2a3c2502020-06-16 17:48:35 -0700169declare_binder_interface! {
170 ITest["android.os.ITest"] {
171 native: BnTest(on_transact),
172 proxy: BpTest {
173 x: i32 = 100
174 },
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000175 async: IATest,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700176 }
177}
178
179fn on_transact(
180 service: &dyn ITest,
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700181 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000182 _data: &BorrowedParcel<'_>,
183 reply: &mut BorrowedParcel<'_>,
Stephen Crane2a3c2502020-06-16 17:48:35 -0700184) -> binder::Result<()> {
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700185 match code.try_into()? {
186 TestTransactionCode::Test => reply.write(&service.test()?),
Stephen Crane2a3297f2021-06-11 16:48:10 -0700187 TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?),
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700188 TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?),
189 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700190}
191
192impl ITest for BpTest {
193 fn test(&self) -> binder::Result<String> {
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700194 let reply =
195 self.binder
196 .transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(()))?;
197 reply.read()
198 }
199
Stephen Crane2a3297f2021-06-11 16:48:10 -0700200 fn get_dump_args(&self) -> binder::Result<Vec<String>> {
201 let reply =
202 self.binder
203 .transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(()))?;
204 reply.read()
205 }
206
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700207 fn get_selinux_context(&self) -> binder::Result<String> {
208 let reply = self.binder.transact(
209 TestTransactionCode::GetSelinuxContext as TransactionCode,
210 0,
211 |_| Ok(()),
212 )?;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700213 reply.read()
214 }
215}
216
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000217impl<P: binder::BinderAsyncPool> IATest<P> for BpTest {
218 fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
219 let binder = self.binder.clone();
220 P::spawn(
Alice Ryhl8618c482021-11-09 15:35:35 +0000221 move || binder.transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(())),
222 |reply| async move { reply?.read() }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000223 )
224 }
225
226 fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>> {
227 let binder = self.binder.clone();
228 P::spawn(
Alice Ryhl8618c482021-11-09 15:35:35 +0000229 move || binder.transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(())),
230 |reply| async move { reply?.read() }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000231 )
232 }
233
234 fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
235 let binder = self.binder.clone();
236 P::spawn(
Alice Ryhl8618c482021-11-09 15:35:35 +0000237 move || binder.transact(TestTransactionCode::GetSelinuxContext as TransactionCode, 0, |_| Ok(())),
238 |reply| async move { reply?.read() }
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000239 )
240 }
241}
242
Stephen Crane2a3c2502020-06-16 17:48:35 -0700243impl ITest for Binder<BnTest> {
244 fn test(&self) -> binder::Result<String> {
245 self.0.test()
246 }
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700247
Stephen Crane2a3297f2021-06-11 16:48:10 -0700248 fn get_dump_args(&self) -> binder::Result<Vec<String>> {
249 self.0.get_dump_args()
250 }
251
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700252 fn get_selinux_context(&self) -> binder::Result<String> {
253 self.0.get_selinux_context()
254 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700255}
256
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000257impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> {
258 fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
259 let res = self.0.test();
260 Box::pin(async move { res })
261 }
262
263 fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>> {
264 let res = self.0.get_dump_args();
265 Box::pin(async move { res })
266 }
267
268 fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
269 let res = self.0.get_selinux_context();
270 Box::pin(async move { res })
271 }
272}
273
Stephen Crane669deb62020-09-10 17:31:39 -0700274/// Trivial testing binder interface
275pub trait ITestSameDescriptor: Interface {}
276
277declare_binder_interface! {
278 ITestSameDescriptor["android.os.ITest"] {
279 native: BnTestSameDescriptor(on_transact_same_descriptor),
280 proxy: BpTestSameDescriptor,
281 }
282}
283
284fn on_transact_same_descriptor(
285 _service: &dyn ITestSameDescriptor,
286 _code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000287 _data: &BorrowedParcel<'_>,
288 _reply: &mut BorrowedParcel<'_>,
Stephen Crane669deb62020-09-10 17:31:39 -0700289) -> binder::Result<()> {
290 Ok(())
291}
292
293impl ITestSameDescriptor for BpTestSameDescriptor {}
294
295impl ITestSameDescriptor for Binder<BnTestSameDescriptor> {}
296
Stephen Crane7bca1052021-10-25 17:52:51 -0700297declare_binder_enum! {
298 TestEnum : [i32; 3] {
299 FOO = 1,
300 BAR = 2,
301 BAZ = 3,
302 }
303}
304
305declare_binder_enum! {
306 #[deprecated(since = "1.0.0")]
307 TestDeprecatedEnum : [i32; 3] {
308 FOO = 1,
309 BAR = 2,
310 BAZ = 3,
311 }
312}
313
Stephen Crane2a3c2502020-06-16 17:48:35 -0700314#[cfg(test)]
315mod tests {
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700316 use selinux_bindgen as selinux_sys;
317 use std::ffi::CStr;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700318 use std::fs::File;
319 use std::process::{Child, Command};
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700320 use std::ptr;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700321 use std::sync::atomic::{AtomicBool, Ordering};
322 use std::sync::Arc;
323 use std::thread;
324 use std::time::Duration;
325
Andrew Walbran12400d82021-03-04 17:04:34 +0000326 use binder::{
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000327 Binder, BinderFeatures, DeathRecipient, FromIBinder, IBinder, IBinderInternal, Interface,
328 SpIBinder, StatusCode, Strong,
Andrew Walbran12400d82021-03-04 17:04:34 +0000329 };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700330
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000331 use binder_tokio::Tokio;
332
333 use super::{BnTest, ITest, IATest, ITestSameDescriptor, TestService, RUST_SERVICE_BINARY};
Stephen Crane2a3c2502020-06-16 17:48:35 -0700334
335 pub struct ScopedServiceProcess(Child);
336
337 impl ScopedServiceProcess {
338 pub fn new(identifier: &str) -> Self {
339 Self::new_internal(identifier, None)
340 }
341
342 pub fn new_with_extension(identifier: &str, extension: &str) -> Self {
343 Self::new_internal(identifier, Some(extension))
344 }
345
346 fn new_internal(identifier: &str, extension: Option<&str>) -> Self {
347 let mut binary_path =
348 std::env::current_exe().expect("Could not retrieve current executable path");
349 binary_path.pop();
350 binary_path.push(RUST_SERVICE_BINARY);
351 let mut command = Command::new(&binary_path);
352 command.arg(identifier);
353 if let Some(ext) = extension {
354 command.arg(ext);
355 }
356 let child = command.spawn().expect("Could not start service");
357 Self(child)
358 }
359 }
360
361 impl Drop for ScopedServiceProcess {
362 fn drop(&mut self) {
363 self.0.kill().expect("Could not kill child process");
364 self.0
365 .wait()
366 .expect("Could not wait for child process to die");
367 }
368 }
369
370 #[test]
371 fn check_services() {
372 let mut sm = binder::get_service("manager").expect("Did not get manager binder service");
373 assert!(sm.is_binder_alive());
374 assert!(sm.ping_binder().is_ok());
375
376 assert!(binder::get_service("this_service_does_not_exist").is_none());
377 assert_eq!(
378 binder::get_interface::<dyn ITest>("this_service_does_not_exist").err(),
379 Some(StatusCode::NAME_NOT_FOUND)
380 );
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000381 assert_eq!(
382 binder::get_interface::<dyn IATest<Tokio>>("this_service_does_not_exist").err(),
383 Some(StatusCode::NAME_NOT_FOUND)
384 );
Stephen Crane2a3c2502020-06-16 17:48:35 -0700385
386 // The service manager service isn't an ITest, so this must fail.
387 assert_eq!(
388 binder::get_interface::<dyn ITest>("manager").err(),
389 Some(StatusCode::BAD_TYPE)
390 );
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000391 assert_eq!(
392 binder::get_interface::<dyn IATest<Tokio>>("manager").err(),
393 Some(StatusCode::BAD_TYPE)
394 );
Stephen Crane2a3c2502020-06-16 17:48:35 -0700395 }
396
Alice Ryhl929804f2021-11-02 12:04:39 +0000397 #[tokio::test]
398 async fn check_services_async() {
399 let mut sm = binder::get_service("manager").expect("Did not get manager binder service");
400 assert!(sm.is_binder_alive());
401 assert!(sm.ping_binder().is_ok());
402
403 assert!(binder::get_service("this_service_does_not_exist").is_none());
404 assert_eq!(
405 binder_tokio::get_interface::<dyn ITest>("this_service_does_not_exist").await.err(),
406 Some(StatusCode::NAME_NOT_FOUND)
407 );
408 assert_eq!(
409 binder_tokio::get_interface::<dyn IATest<Tokio>>("this_service_does_not_exist").await.err(),
410 Some(StatusCode::NAME_NOT_FOUND)
411 );
412
413 // The service manager service isn't an ITest, so this must fail.
414 assert_eq!(
415 binder_tokio::get_interface::<dyn ITest>("manager").await.err(),
416 Some(StatusCode::BAD_TYPE)
417 );
418 assert_eq!(
419 binder_tokio::get_interface::<dyn IATest<Tokio>>("manager").await.err(),
420 Some(StatusCode::BAD_TYPE)
421 );
422 }
423
Stephen Crane2a3c2502020-06-16 17:48:35 -0700424 #[test]
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000425 fn check_wait_for_service() {
426 let mut sm =
427 binder::wait_for_service("manager").expect("Did not get manager binder service");
428 assert!(sm.is_binder_alive());
429 assert!(sm.ping_binder().is_ok());
430
431 // The service manager service isn't an ITest, so this must fail.
432 assert_eq!(
433 binder::wait_for_interface::<dyn ITest>("manager").err(),
434 Some(StatusCode::BAD_TYPE)
435 );
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000436 assert_eq!(
437 binder::wait_for_interface::<dyn IATest<Tokio>>("manager").err(),
438 Some(StatusCode::BAD_TYPE)
439 );
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000440 }
441
442 #[test]
Stephen Crane2a3c2502020-06-16 17:48:35 -0700443 fn trivial_client() {
444 let service_name = "trivial_client_test";
445 let _process = ScopedServiceProcess::new(service_name);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800446 let test_client: Strong<dyn ITest> =
Stephen Crane2a3c2502020-06-16 17:48:35 -0700447 binder::get_interface(service_name).expect("Did not get manager binder service");
448 assert_eq!(test_client.test().unwrap(), "trivial_client_test");
449 }
450
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000451 #[tokio::test]
452 async fn trivial_client_async() {
453 let service_name = "trivial_client_test";
454 let _process = ScopedServiceProcess::new(service_name);
455 let test_client: Strong<dyn IATest<Tokio>> =
Alice Ryhl929804f2021-11-02 12:04:39 +0000456 binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service");
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000457 assert_eq!(test_client.test().await.unwrap(), "trivial_client_test");
458 }
459
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700460 #[test]
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000461 fn wait_for_trivial_client() {
462 let service_name = "wait_for_trivial_client_test";
463 let _process = ScopedServiceProcess::new(service_name);
464 let test_client: Strong<dyn ITest> =
465 binder::wait_for_interface(service_name).expect("Did not get manager binder service");
466 assert_eq!(test_client.test().unwrap(), "wait_for_trivial_client_test");
467 }
468
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000469 #[tokio::test]
470 async fn wait_for_trivial_client_async() {
471 let service_name = "wait_for_trivial_client_test";
472 let _process = ScopedServiceProcess::new(service_name);
473 let test_client: Strong<dyn IATest<Tokio>> =
Alice Ryhl929804f2021-11-02 12:04:39 +0000474 binder_tokio::wait_for_interface(service_name).await.expect("Did not get manager binder service");
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000475 assert_eq!(test_client.test().await.unwrap(), "wait_for_trivial_client_test");
476 }
477
478 fn get_expected_selinux_context() -> &'static str {
479 unsafe {
480 let mut out_ptr = ptr::null_mut();
481 assert_eq!(selinux_sys::getcon(&mut out_ptr), 0);
482 assert!(!out_ptr.is_null());
483 CStr::from_ptr(out_ptr)
484 .to_str()
485 .expect("context was invalid UTF-8")
486 }
487 }
488
Andrew Walbranc3ce5c32021-06-03 16:15:56 +0000489 #[test]
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700490 fn get_selinux_context() {
491 let service_name = "get_selinux_context";
492 let _process = ScopedServiceProcess::new(service_name);
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800493 let test_client: Strong<dyn ITest> =
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700494 binder::get_interface(service_name).expect("Did not get manager binder service");
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700495 assert_eq!(
496 test_client.get_selinux_context().unwrap(),
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000497 get_expected_selinux_context()
498 );
499 }
500
501 #[tokio::test]
502 async fn get_selinux_context_async() {
503 let service_name = "get_selinux_context";
504 let _process = ScopedServiceProcess::new(service_name);
505 let test_client: Strong<dyn IATest<Tokio>> =
Alice Ryhl929804f2021-11-02 12:04:39 +0000506 binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service");
Alice Ryhl05f5a2c2021-09-15 12:56:10 +0000507 assert_eq!(
508 test_client.get_selinux_context().await.unwrap(),
509 get_expected_selinux_context()
Janis Danisevskis798a09a2020-08-18 08:35:38 -0700510 );
511 }
512
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000513 struct Bools {
514 binder_died: Arc<AtomicBool>,
515 binder_dealloc: Arc<AtomicBool>,
516 }
517
518 impl Bools {
519 fn is_dead(&self) -> bool {
520 self.binder_died.load(Ordering::Relaxed)
521 }
522 fn assert_died(&self) {
523 assert!(
524 self.is_dead(),
525 "Did not receive death notification"
526 );
527 }
528 fn assert_dropped(&self) {
529 assert!(
530 self.binder_dealloc.load(Ordering::Relaxed),
531 "Did not dealloc death notification"
532 );
533 }
534 fn assert_not_dropped(&self) {
535 assert!(
536 !self.binder_dealloc.load(Ordering::Relaxed),
537 "Dealloc death notification too early"
538 );
539 }
540 }
541
542 fn register_death_notification(binder: &mut SpIBinder) -> (Bools, DeathRecipient) {
Stephen Crane2a3c2502020-06-16 17:48:35 -0700543 let binder_died = Arc::new(AtomicBool::new(false));
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000544 let binder_dealloc = Arc::new(AtomicBool::new(false));
545
546 struct SetOnDrop {
547 binder_dealloc: Arc<AtomicBool>,
548 }
549 impl Drop for SetOnDrop {
550 fn drop(&mut self) {
551 self.binder_dealloc.store(true, Ordering::Relaxed);
552 }
553 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700554
555 let mut death_recipient = {
556 let flag = binder_died.clone();
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000557 let set_on_drop = SetOnDrop {
558 binder_dealloc: binder_dealloc.clone(),
559 };
Stephen Crane2a3c2502020-06-16 17:48:35 -0700560 DeathRecipient::new(move || {
561 flag.store(true, Ordering::Relaxed);
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000562 // Force the closure to take ownership of set_on_drop. When the closure is
563 // dropped, the destructor of `set_on_drop` will run.
564 let _ = &set_on_drop;
Stephen Crane2a3c2502020-06-16 17:48:35 -0700565 })
566 };
567
568 binder
569 .link_to_death(&mut death_recipient)
570 .expect("link_to_death failed");
571
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000572 let bools = Bools {
573 binder_died,
574 binder_dealloc,
575 };
576
577 (bools, death_recipient)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700578 }
579
580 /// Killing a remote service should unregister the service and trigger
581 /// death notifications.
582 #[test]
583 fn test_death_notifications() {
584 binder::ProcessState::start_thread_pool();
585
586 let service_name = "test_death_notifications";
587 let service_process = ScopedServiceProcess::new(service_name);
588 let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
589
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000590 let (bools, recipient) = register_death_notification(&mut remote);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700591
592 drop(service_process);
593 remote
594 .ping_binder()
595 .expect_err("Service should have died already");
596
597 // Pause to ensure any death notifications get delivered
598 thread::sleep(Duration::from_secs(1));
599
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000600 bools.assert_died();
601 bools.assert_not_dropped();
602
603 drop(recipient);
604
605 bools.assert_dropped();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700606 }
607
608 /// Test unregistering death notifications.
609 #[test]
610 fn test_unregister_death_notifications() {
611 binder::ProcessState::start_thread_pool();
612
613 let service_name = "test_unregister_death_notifications";
614 let service_process = ScopedServiceProcess::new(service_name);
615 let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
616
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000617 let (bools, mut recipient) = register_death_notification(&mut remote);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700618
619 remote
620 .unlink_to_death(&mut recipient)
621 .expect("Could not unlink death notifications");
622
623 drop(service_process);
624 remote
625 .ping_binder()
626 .expect_err("Service should have died already");
627
628 // Pause to ensure any death notifications get delivered
629 thread::sleep(Duration::from_secs(1));
630
631 assert!(
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000632 !bools.is_dead(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700633 "Received unexpected death notification after unlinking",
634 );
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000635
636 bools.assert_not_dropped();
637 drop(recipient);
638 bools.assert_dropped();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700639 }
640
641 /// Dropping a remote handle should unregister any death notifications.
642 #[test]
643 fn test_death_notification_registration_lifetime() {
644 binder::ProcessState::start_thread_pool();
645
646 let service_name = "test_death_notification_registration_lifetime";
647 let service_process = ScopedServiceProcess::new(service_name);
648 let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
649
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000650 let (bools, recipient) = register_death_notification(&mut remote);
Stephen Crane2a3c2502020-06-16 17:48:35 -0700651
652 // This should automatically unregister our death notification.
653 drop(remote);
654
655 drop(service_process);
656
657 // Pause to ensure any death notifications get delivered
658 thread::sleep(Duration::from_secs(1));
659
660 // We dropped the remote handle, so we should not receive the death
661 // notification when the remote process dies here.
662 assert!(
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000663 !bools.is_dead(),
Stephen Crane2a3c2502020-06-16 17:48:35 -0700664 "Received unexpected death notification after dropping remote handle"
665 );
Alice Ryhlea9d9d22021-08-27 07:51:30 +0000666
667 bools.assert_not_dropped();
668 drop(recipient);
669 bools.assert_dropped();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700670 }
671
672 /// Test IBinder interface methods not exercised elsewhere.
673 #[test]
674 fn test_misc_ibinder() {
675 let service_name = "rust_test_ibinder";
676
677 {
678 let _process = ScopedServiceProcess::new(service_name);
679
Stephen Crane2a3297f2021-06-11 16:48:10 -0700680 let test_client: Strong<dyn ITest> =
681 binder::get_interface(service_name)
682 .expect("Did not get test binder service");
683 let mut remote = test_client.as_binder();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700684 assert!(remote.is_binder_alive());
685 remote.ping_binder().expect("Could not ping remote service");
686
Stephen Crane2a3297f2021-06-11 16:48:10 -0700687 let dump_args = ["dump", "args", "for", "testing"];
688
Stephen Crane2a3c2502020-06-16 17:48:35 -0700689 let null_out = File::open("/dev/null").expect("Could not open /dev/null");
690 remote
Stephen Crane2a3297f2021-06-11 16:48:10 -0700691 .dump(&null_out, &dump_args)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700692 .expect("Could not dump remote service");
Stephen Crane2a3297f2021-06-11 16:48:10 -0700693
694 let remote_args = test_client.get_dump_args().expect("Could not fetched dumped args");
695 assert_eq!(dump_args, remote_args[..], "Remote args don't match call to dump");
Stephen Crane2a3c2502020-06-16 17:48:35 -0700696 }
697
698 // get/set_extensions is tested in test_extensions()
699
700 // transact is tested everywhere else, and we can't make raw
701 // transactions outside the [FIRST_CALL_TRANSACTION,
702 // LAST_CALL_TRANSACTION] range from the NDK anyway.
703
704 // link_to_death is tested in test_*_death_notification* tests.
705 }
706
707 #[test]
708 fn test_extensions() {
709 let service_name = "rust_test_extensions";
710 let extension_name = "rust_test_extensions_ext";
711
712 {
713 let _process = ScopedServiceProcess::new(service_name);
714
715 let mut remote = binder::get_service(service_name);
716 assert!(remote.is_binder_alive());
717
718 let extension = remote
719 .get_extension()
720 .expect("Could not check for an extension");
721 assert!(extension.is_none());
722 }
723
724 {
725 let _process = ScopedServiceProcess::new_with_extension(service_name, extension_name);
726
727 let mut remote = binder::get_service(service_name);
728 assert!(remote.is_binder_alive());
729
730 let maybe_extension = remote
731 .get_extension()
732 .expect("Could not check for an extension");
733
734 let extension = maybe_extension.expect("Remote binder did not have an extension");
735
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800736 let extension: Strong<dyn ITest> = FromIBinder::try_from(extension)
Stephen Crane2a3c2502020-06-16 17:48:35 -0700737 .expect("Extension could not be converted to the expected interface");
738
739 assert_eq!(extension.test().unwrap(), extension_name);
740 }
741 }
Stephen Crane669deb62020-09-10 17:31:39 -0700742
743 /// Test re-associating a local binder object with a different class.
744 ///
745 /// This is needed because different binder service (e.g. NDK vs Rust)
746 /// implementations are incompatible and must not be interchanged. A local
747 /// service with the same descriptor string but a different class pointer
748 /// may have been created by an NDK service and is therefore incompatible
749 /// with the Rust service implementation. It must be treated as remote and
750 /// all API calls parceled and sent through transactions.
751 ///
752 /// Further tests of this behavior with the C NDK and Rust API are in
753 /// rust_ndk_interop.rs
754 #[test]
755 fn associate_existing_class() {
Stephen Crane2a3297f2021-06-11 16:48:10 -0700756 let service = Binder::new(BnTest(Box::new(TestService::new("testing_service"))));
Stephen Crane669deb62020-09-10 17:31:39 -0700757
758 // This should succeed although we will have to treat the service as
759 // remote.
Andrew Walbran12400d82021-03-04 17:04:34 +0000760 let _interface: Strong<dyn ITestSameDescriptor> =
761 FromIBinder::try_from(service.as_binder())
762 .expect("Could not re-interpret service as the ITestSameDescriptor interface");
Stephen Crane669deb62020-09-10 17:31:39 -0700763 }
764
765 /// Test that we can round-trip a rust service through a generic IBinder
766 #[test]
767 fn reassociate_rust_binder() {
768 let service_name = "testing_service";
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000769 let service_ibinder = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700770 TestService::new(service_name),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000771 BinderFeatures::default(),
772 )
Andrew Walbran12400d82021-03-04 17:04:34 +0000773 .as_binder();
Stephen Crane669deb62020-09-10 17:31:39 -0700774
Andrew Walbran12400d82021-03-04 17:04:34 +0000775 let service: Strong<dyn ITest> = service_ibinder
776 .into_interface()
Stephen Crane669deb62020-09-10 17:31:39 -0700777 .expect("Could not reassociate the generic ibinder");
778
779 assert_eq!(service.test().unwrap(), service_name);
780 }
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800781
782 #[test]
783 fn weak_binder_upgrade() {
784 let service_name = "testing_service";
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000785 let service = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700786 TestService::new(service_name),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000787 BinderFeatures::default(),
788 );
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800789
790 let weak = Strong::downgrade(&service);
791
792 let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
793
794 assert_eq!(service, upgraded);
795 }
796
797 #[test]
798 fn weak_binder_upgrade_dead() {
799 let service_name = "testing_service";
800 let weak = {
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000801 let service = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700802 TestService::new(service_name),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000803 BinderFeatures::default(),
804 );
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800805
806 Strong::downgrade(&service)
807 };
808
809 assert_eq!(weak.upgrade(), Err(StatusCode::DEAD_OBJECT));
810 }
811
812 #[test]
813 fn weak_binder_clone() {
814 let service_name = "testing_service";
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000815 let service = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700816 TestService::new(service_name),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000817 BinderFeatures::default(),
818 );
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800819
820 let weak = Strong::downgrade(&service);
821 let cloned = weak.clone();
822 assert_eq!(weak, cloned);
823
824 let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
825 let clone_upgraded = cloned.upgrade().expect("Could not upgrade weak binder");
826
827 assert_eq!(service, upgraded);
828 assert_eq!(service, clone_upgraded);
829 }
830
831 #[test]
832 #[allow(clippy::eq_op)]
833 fn binder_ord() {
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000834 let service1 = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700835 TestService::new("testing_service1"),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000836 BinderFeatures::default(),
837 );
838 let service2 = BnTest::new_binder(
Stephen Crane2a3297f2021-06-11 16:48:10 -0700839 TestService::new("testing_service2"),
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000840 BinderFeatures::default(),
841 );
Stephen Craneddb3e6d2020-12-18 13:27:22 -0800842
843 assert!(!(service1 < service1));
844 assert!(!(service1 > service1));
845 assert_eq!(service1 < service2, !(service2 < service1));
846 }
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000847
848 #[test]
849 fn binder_parcel_mixup() {
850 let service1 = BnTest::new_binder(
851 TestService::new("testing_service1"),
852 BinderFeatures::default(),
853 );
854 let service2 = BnTest::new_binder(
855 TestService::new("testing_service2"),
856 BinderFeatures::default(),
857 );
858
859 let service1 = service1.as_binder();
860 let service2 = service2.as_binder();
861
862 let parcel = service1.prepare_transact().unwrap();
863 let res = service2.submit_transact(super::TestTransactionCode::Test as binder::TransactionCode, parcel, 0);
864
865 match res {
866 Ok(_) => panic!("submit_transact should fail"),
867 Err(err) => assert_eq!(err, binder::StatusCode::BAD_VALUE),
868 }
869 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700870}