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 //! Included as a module in the binder crate internal tests for internal API
18 //! access.
19
20 use binder::declare_binder_interface;
21 use binder::parcel::ParcelFileDescriptor;
22 use binder::{
23 Binder, BinderFeatures, ExceptionCode, Interface, Parcel, Result, SpIBinder, Status,
24 StatusCode, TransactionCode,
25 };
26
27 use std::ffi::{c_void, CStr, CString};
28 use std::sync::Once;
29
30 #[allow(
31 non_camel_case_types,
32 non_snake_case,
33 non_upper_case_globals,
34 unused,
35 improper_ctypes,
36 missing_docs,
37 clippy::all
38 )]
39 mod bindings {
40 include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
41 }
42
43 macro_rules! assert_eq {
44 ($left:expr, $right:expr $(,)?) => {
45 match (&$left, &$right) {
46 (left, right) => {
47 if *left != *right {
48 eprintln!(
49 "assertion failed: `{:?}` == `{:?}`, {}:{}:{}",
50 &*left,
51 &*right,
52 file!(),
53 line!(),
54 column!()
55 );
56 return Err(StatusCode::FAILED_TRANSACTION);
57 }
58 }
59 }
60 };
61 }
62
63 macro_rules! assert {
64 ($expr:expr) => {
65 if !$expr {
66 eprintln!(
67 "assertion failed: `{:?}`, {}:{}:{}",
68 $expr,
69 file!(),
70 line!(),
71 column!()
72 );
73 return Err(StatusCode::FAILED_TRANSACTION);
74 }
75 };
76 }
77
78 static SERVICE_ONCE: Once = Once::new();
79 static mut SERVICE: Option<SpIBinder> = None;
80
81 /// Start binder service and return a raw AIBinder pointer to it.
82 ///
83 /// Safe to call multiple times, only creates the service once.
84 #[no_mangle]
rust_service() -> *mut c_void85 pub extern "C" fn rust_service() -> *mut c_void {
86 unsafe {
87 SERVICE_ONCE.call_once(|| {
88 SERVICE = Some(BnReadParcelTest::new_binder((), BinderFeatures::default()).as_binder());
89 });
90 SERVICE.as_ref().unwrap().as_raw().cast()
91 }
92 }
93
94 /// Empty interface just to use the declare_binder_interface macro
95 pub trait ReadParcelTest: Interface {}
96
97 declare_binder_interface! {
98 ReadParcelTest["read_parcel_test"] {
99 native: BnReadParcelTest(on_transact),
100 proxy: BpReadParcelTest,
101 }
102 }
103
104 impl ReadParcelTest for Binder<BnReadParcelTest> {}
105
106 impl ReadParcelTest for BpReadParcelTest {}
107
108 impl ReadParcelTest for () {}
109
110 #[allow(clippy::float_cmp)]
on_transact( _service: &dyn ReadParcelTest, code: TransactionCode, parcel: &Parcel, reply: &mut Parcel, ) -> Result<()>111 fn on_transact(
112 _service: &dyn ReadParcelTest,
113 code: TransactionCode,
114 parcel: &Parcel,
115 reply: &mut Parcel,
116 ) -> Result<()> {
117 match code {
118 bindings::Transaction_TEST_BOOL => {
119 assert_eq!(parcel.read::<bool>()?, true);
120 assert_eq!(parcel.read::<bool>()?, false);
121 assert_eq!(parcel.read::<Vec<bool>>()?, unsafe {
122 bindings::TESTDATA_BOOL
123 });
124 assert_eq!(parcel.read::<Option<Vec<bool>>>()?, None);
125
126 reply.write(&true)?;
127 reply.write(&false)?;
128 reply.write(&unsafe { bindings::TESTDATA_BOOL }[..])?;
129 reply.write(&(None as Option<Vec<bool>>))?;
130 }
131 bindings::Transaction_TEST_BYTE => {
132 assert_eq!(parcel.read::<i8>()?, 0);
133 assert_eq!(parcel.read::<i8>()?, 1);
134 assert_eq!(parcel.read::<i8>()?, i8::max_value());
135 assert_eq!(parcel.read::<Vec<i8>>()?, unsafe { bindings::TESTDATA_I8 });
136 assert_eq!(parcel.read::<Vec<u8>>()?, unsafe { bindings::TESTDATA_U8 });
137 assert_eq!(parcel.read::<Option<Vec<i8>>>()?, None);
138
139 reply.write(&0i8)?;
140 reply.write(&1i8)?;
141 reply.write(&i8::max_value())?;
142 reply.write(&unsafe { bindings::TESTDATA_I8 }[..])?;
143 reply.write(&unsafe { bindings::TESTDATA_U8 }[..])?;
144 reply.write(&(None as Option<Vec<i8>>))?;
145 }
146 bindings::Transaction_TEST_U16 => {
147 assert_eq!(parcel.read::<u16>()?, 0);
148 assert_eq!(parcel.read::<u16>()?, 1);
149 assert_eq!(parcel.read::<u16>()?, u16::max_value());
150 assert_eq!(parcel.read::<Vec<u16>>()?, unsafe {
151 bindings::TESTDATA_CHARS
152 });
153 assert_eq!(parcel.read::<Option<Vec<u16>>>()?, None);
154
155 reply.write(&0u16)?;
156 reply.write(&1u16)?;
157 reply.write(&u16::max_value())?;
158 reply.write(&unsafe { bindings::TESTDATA_CHARS }[..])?;
159 reply.write(&(None as Option<Vec<u16>>))?;
160 }
161 bindings::Transaction_TEST_I32 => {
162 assert_eq!(parcel.read::<i32>()?, 0);
163 assert_eq!(parcel.read::<i32>()?, 1);
164 assert_eq!(parcel.read::<i32>()?, i32::max_value());
165 assert_eq!(parcel.read::<Vec<i32>>()?, unsafe {
166 bindings::TESTDATA_I32
167 });
168 assert_eq!(parcel.read::<Option<Vec<i32>>>()?, None);
169
170 reply.write(&0i32)?;
171 reply.write(&1i32)?;
172 reply.write(&i32::max_value())?;
173 reply.write(&unsafe { bindings::TESTDATA_I32 }[..])?;
174 reply.write(&(None as Option<Vec<i32>>))?;
175 }
176 bindings::Transaction_TEST_I64 => {
177 assert_eq!(parcel.read::<i64>()?, 0);
178 assert_eq!(parcel.read::<i64>()?, 1);
179 assert_eq!(parcel.read::<i64>()?, i64::max_value());
180 assert_eq!(parcel.read::<Vec<i64>>()?, unsafe {
181 bindings::TESTDATA_I64
182 });
183 assert_eq!(parcel.read::<Option<Vec<i64>>>()?, None);
184
185 reply.write(&0i64)?;
186 reply.write(&1i64)?;
187 reply.write(&i64::max_value())?;
188 reply.write(&unsafe { bindings::TESTDATA_I64 }[..])?;
189 reply.write(&(None as Option<Vec<i64>>))?;
190 }
191 bindings::Transaction_TEST_U64 => {
192 assert_eq!(parcel.read::<u64>()?, 0);
193 assert_eq!(parcel.read::<u64>()?, 1);
194 assert_eq!(parcel.read::<u64>()?, u64::max_value());
195 assert_eq!(parcel.read::<Vec<u64>>()?, unsafe {
196 bindings::TESTDATA_U64
197 });
198 assert_eq!(parcel.read::<Option<Vec<u64>>>()?, None);
199
200 reply.write(&0u64)?;
201 reply.write(&1u64)?;
202 reply.write(&u64::max_value())?;
203 reply.write(&unsafe { bindings::TESTDATA_U64 }[..])?;
204 reply.write(&(None as Option<Vec<u64>>))?;
205 }
206 bindings::Transaction_TEST_F32 => {
207 assert_eq!(parcel.read::<f32>()?, 0f32);
208 let floats = parcel.read::<Vec<f32>>()?;
209 assert!(floats[0].is_nan());
210 assert_eq!(floats[1..], unsafe { bindings::TESTDATA_FLOAT }[1..]);
211 assert_eq!(parcel.read::<Option<Vec<f32>>>()?, None);
212
213 reply.write(&0f32)?;
214 reply.write(&unsafe { bindings::TESTDATA_FLOAT }[..])?;
215 reply.write(&(None as Option<Vec<f32>>))?;
216 }
217 bindings::Transaction_TEST_F64 => {
218 assert_eq!(parcel.read::<f64>()?, 0f64);
219 let doubles = parcel.read::<Vec<f64>>()?;
220 assert!(doubles[0].is_nan());
221 assert_eq!(doubles[1..], unsafe { bindings::TESTDATA_DOUBLE }[1..]);
222 assert_eq!(parcel.read::<Option<Vec<f64>>>()?, None);
223
224 reply.write(&0f64)?;
225 reply.write(&unsafe { bindings::TESTDATA_DOUBLE }[..])?;
226 reply.write(&(None as Option<Vec<f64>>))?;
227 }
228 bindings::Transaction_TEST_STRING => {
229 let s: Option<String> = parcel.read()?;
230 assert_eq!(s.as_deref(), Some("testing"));
231 let s: Option<String> = parcel.read()?;
232 assert_eq!(s, None);
233 let s: Option<Vec<Option<String>>> = parcel.read()?;
234 for (s, expected) in s
235 .unwrap()
236 .iter()
237 .zip(unsafe { bindings::TESTDATA_STRS }.iter())
238 {
239 let expected = unsafe {
240 expected
241 .as_ref()
242 .and_then(|e| CStr::from_ptr(e).to_str().ok())
243 };
244 assert_eq!(s.as_deref(), expected);
245 }
246 let s: Option<Vec<Option<String>>> = parcel.read()?;
247 assert_eq!(s, None);
248
249 let strings: Vec<Option<String>> = unsafe {
250 bindings::TESTDATA_STRS
251 .iter()
252 .map(|s| {
253 s.as_ref().map(|s| {
254 CStr::from_ptr(s)
255 .to_str()
256 .expect("String was not UTF-8")
257 .to_owned()
258 })
259 })
260 .collect()
261 };
262
263 reply.write("testing")?;
264 reply.write(&(None as Option<String>))?;
265 reply.write(&strings)?;
266 reply.write(&(None as Option<Vec<String>>))?;
267 }
268 bindings::Transaction_TEST_FILE_DESCRIPTOR => {
269 let file1 = parcel.read::<ParcelFileDescriptor>()?;
270 let file2 = parcel.read::<ParcelFileDescriptor>()?;
271 let files = parcel.read::<Vec<Option<ParcelFileDescriptor>>>()?;
272
273 reply.write(&file1)?;
274 reply.write(&file2)?;
275 reply.write(&files)?;
276 }
277 bindings::Transaction_TEST_IBINDER => {
278 assert!(parcel.read::<Option<SpIBinder>>()?.is_some());
279 assert!(parcel.read::<Option<SpIBinder>>()?.is_none());
280 let ibinders = parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.unwrap();
281 assert_eq!(ibinders.len(), 2);
282 assert!(ibinders[0].is_some());
283 assert!(ibinders[1].is_none());
284 assert!(parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.is_none());
285
286 let service = unsafe {
287 SERVICE
288 .as_ref()
289 .expect("Global binder service not initialized")
290 .clone()
291 };
292 reply.write(&service)?;
293 reply.write(&(None as Option<&SpIBinder>))?;
294 reply.write(&[Some(&service), None][..])?;
295 reply.write(&(None as Option<Vec<Option<&SpIBinder>>>))?;
296 }
297 bindings::Transaction_TEST_STATUS => {
298 let status: Status = parcel.read()?;
299 assert!(status.is_ok());
300 let status: Status = parcel.read()?;
301 assert_eq!(status.exception_code(), ExceptionCode::NULL_POINTER);
302 assert_eq!(
303 status.get_description(),
304 "Status(-4, EX_NULL_POINTER): 'a status message'"
305 );
306 let status: Status = parcel.read()?;
307 assert_eq!(status.service_specific_error(), 42);
308 assert_eq!(
309 status.get_description(),
310 "Status(-8, EX_SERVICE_SPECIFIC): '42: a service-specific error'"
311 );
312
313 reply.write(&Status::ok())?;
314 reply.write(&Status::new_exception(
315 ExceptionCode::NULL_POINTER,
316 Some(&CString::new("a status message").unwrap()),
317 ))?;
318 reply.write(&Status::new_service_specific_error(
319 42,
320 Some(&CString::new("a service-specific error").unwrap()),
321 ))?;
322 }
323 bindings::Transaction_TEST_FAIL => {
324 assert!(false);
325 }
326 _ => return Err(StatusCode::UNKNOWN_TRANSACTION),
327 }
328
329 assert_eq!(parcel.read::<i32>(), Err(StatusCode::NOT_ENOUGH_DATA));
330 Ok(())
331 }
332