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