1 /*
2  * Copyright (C) 2023 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 #![cfg(test)]
17 
18 use binder::{BinderFeatures, IBinder, Status, StatusCode, Strong};
19 use binder_rpc_test_aidl::aidl::IBinderRpcSession::{BnBinderRpcSession, IBinderRpcSession};
20 use binder_rpc_test_aidl::aidl::IBinderRpcTest::{BnBinderRpcTest, IBinderRpcTest};
21 use binder_rpc_test_session::MyBinderRpcSession;
22 use libc::{clock_gettime, CLOCK_REALTIME};
23 use rpcbinder::RpcSession;
24 use trusty_std::ffi::{CString, FallibleCString};
25 
26 test::init!();
27 
28 const SERVICE_PORT: &str = "com.android.trusty.binderRpcTestService.V1";
29 const RUST_SERVICE_PORT: &str = "com.android.trusty.rust.binderRpcTestService.V1";
30 
31 macro_rules! service_test {
32     ($c_name:ident, $rust_name:ident, $body:expr) => {
33         #[test]
34         fn $c_name() {
35             $body(get_service(SERVICE_PORT))
36         }
37         #[test]
38         fn $rust_name() {
39             $body(get_service(RUST_SERVICE_PORT))
40         }
41     };
42 }
43 
get_service(port: &str) -> Strong<dyn IBinderRpcTest>44 fn get_service(port: &str) -> Strong<dyn IBinderRpcTest> {
45     let port = CString::try_new(port).expect("Failed to allocate port name");
46     RpcSession::new().setup_trusty_client(port.as_c_str()).expect("Failed to create session")
47 }
48 
expect_sessions(expected: i32, srv: &Strong<dyn IBinderRpcTest>)49 fn expect_sessions(expected: i32, srv: &Strong<dyn IBinderRpcTest>) {
50     let count = srv.getNumOpenSessions();
51     assert!(count.is_ok());
52     assert_eq!(expected, count.unwrap());
53 }
54 
get_time_ns() -> u6455 fn get_time_ns() -> u64 {
56     let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
57 
58     // Safety: Passing valid pointer to variable ts which lives past end of call
59     assert_eq!(unsafe { clock_gettime(CLOCK_REALTIME, &mut ts) }, 0);
60 
61     ts.tv_sec as u64 * 1_000_000_000u64 + ts.tv_nsec as u64
62 }
63 
get_time_ms() -> u6464 fn get_time_ms() -> u64 {
65     get_time_ns() / 1_000_000u64
66 }
67 
68 // ----------
69 
70 service_test! {ping, ping_rust, |srv: Strong<dyn IBinderRpcTest>| {
71     assert_eq!(srv.as_binder().ping_binder(), Ok(()));
72 }}
73 
74 service_test! {send_something_oneway, send_something_oneway_rust, |srv: Strong<dyn IBinderRpcTest>| {
75     assert_eq!(srv.sendString("Foo"), Ok(()));
76 }}
77 
78 service_test! {send_and_get_result_back, send_and_get_result_back_rust, |srv: Strong<dyn IBinderRpcTest>| {
79     assert_eq!(srv.doubleString("Foo"), Ok(String::from("FooFoo")));
80 }}
81 
82 service_test! {send_and_get_result_back_big, send_and_get_result_back_big_rust, |srv: Strong<dyn IBinderRpcTest>| {
83     let single_len = 512;
84     let single = "a".repeat(single_len);
85     assert_eq!(srv.doubleString(&single), Ok(String::from(single.clone() + &single)));
86 }}
87 
88 service_test! {invalid_null_binder_return, invalid_null_binder_return_rust, |srv: Strong<dyn IBinderRpcTest>| {
89     let binder = srv.getNullBinder();
90     assert!(binder == Err(Status::from(StatusCode::UNEXPECTED_NULL)) || binder == Err(Status::from(StatusCode::UNKNOWN_TRANSACTION)));
91 }}
92 
93 service_test! {call_me_back, call_me_back_rust, |srv: Strong<dyn IBinderRpcTest>| {
94     let binder =
95         BnBinderRpcSession::new_binder(MyBinderRpcSession::new("Foo"), BinderFeatures::default())
96             .as_binder();
97     let result = srv.pingMe(&binder);
98     assert_eq!(result, Ok(0));
99 }}
100 
101 service_test! {repeat_binder, repeat_binder_rust, |srv: Strong<dyn IBinderRpcTest>| {
102     let in_binder =
103         BnBinderRpcSession::new_binder(MyBinderRpcSession::new("Foo"), BinderFeatures::default())
104             .as_binder();
105     let result = srv.repeatBinder(Some(&in_binder));
106     assert_eq!(result.unwrap().unwrap(), in_binder);
107 }}
108 
109 service_test! {repeat_their_binder, repeat_their_binder_rust, |srv: Strong<dyn IBinderRpcTest>| {
110     let session = srv.openSession("Test");
111     assert!(session.is_ok());
112 
113     let in_binder = session.unwrap().as_binder();
114     let out_binder = srv.repeatBinder(Some(&in_binder));
115     assert_eq!(out_binder.unwrap().unwrap(), in_binder);
116 }}
117 
118 service_test! {hold_binder, hold_binder_rust, |srv: Strong<dyn IBinderRpcTest>| {
119     let name = "Foo";
120 
121     let binder =
122         BnBinderRpcSession::new_binder(MyBinderRpcSession::new(name), BinderFeatures::default())
123             .as_binder();
124     assert!(srv.holdBinder(Some(&binder)).is_ok());
125 
126     let held = srv.getHeldBinder();
127     assert!(held.is_ok());
128     let held = held.unwrap();
129     assert!(held.is_some());
130     let held = held.unwrap();
131     assert_eq!(binder, held);
132 
133     let session = held.into_interface::<dyn IBinderRpcSession>();
134     assert!(session.is_ok());
135 
136     let session_name = session.unwrap().getName();
137     assert!(session_name.is_ok());
138     let session_name = session_name.unwrap();
139     assert_eq!(session_name, name);
140 
141     assert!(srv.holdBinder(None).is_ok());
142 }}
143 
144 service_test! {nested_transactions, nested_transactions_rust, |srv: Strong<dyn IBinderRpcTest>| {
145     let binder =
146         BnBinderRpcTest::new_binder(MyBinderRpcSession::new("Nest"), BinderFeatures::default());
147     assert!(srv.nestMe(&binder, 10).is_ok());
148 }}
149 
150 service_test! {same_binder_equality, same_binder_equality_rust, |srv: Strong<dyn IBinderRpcTest>| {
151     let a = srv.alwaysGiveMeTheSameBinder();
152     assert!(a.is_ok());
153 
154     let b = srv.alwaysGiveMeTheSameBinder();
155     assert!(b.is_ok());
156 
157     assert_eq!(a.unwrap(), b.unwrap());
158 }}
159 
160 service_test! {single_session, single_session_rust, |srv: Strong<dyn IBinderRpcTest>| {
161     let session = srv.openSession("aoeu");
162     assert!(session.is_ok());
163     let session = session.unwrap();
164     let name = session.getName();
165     assert!(name.is_ok());
166     assert_eq!(name.unwrap(), "aoeu");
167 
168     let count = srv.getNumOpenSessions();
169     assert!(count.is_ok());
170     assert_eq!(count.unwrap(), 1);
171 
172     drop(session);
173     let count = srv.getNumOpenSessions();
174     assert!(count.is_ok());
175     assert_eq!(count.unwrap(), 0);
176 }}
177 
178 service_test! {many_session, many_session_rust, |srv: Strong<dyn IBinderRpcTest>| {
179     let mut sessions = Vec::new();
180 
181     for i in 0..15 {
182         expect_sessions(i, &srv);
183 
184         let session = srv.openSession(&(i.to_string()));
185         assert!(session.is_ok());
186         sessions.push(session.unwrap());
187     }
188 
189     expect_sessions(sessions.len() as i32, &srv);
190 
191     for i in 0..sessions.len() {
192         let name = sessions[i].getName();
193         assert!(name.is_ok());
194         assert_eq!(name.unwrap(), i.to_string());
195     }
196 
197     expect_sessions(sessions.len() as i32, &srv);
198 
199     while !sessions.is_empty() {
200         sessions.pop();
201 
202         expect_sessions(sessions.len() as i32, &srv);
203     }
204 
205     expect_sessions(0, &srv);
206 }}
207 
208 service_test! {one_way_call_does_not_wait, one_way_call_does_not_wait_rust, |srv: Strong<dyn IBinderRpcTest>| {
209     let really_long_time_ms = 100;
210     let sleep_ms = really_long_time_ms * 5;
211 
212     let before = get_time_ms();
213     let _ = srv.sleepMsAsync(sleep_ms);
214     let after = get_time_ms();
215 
216     assert!(after < before + really_long_time_ms as u64);
217 }}
218