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