blob: 8b04c76b3351f4f72b393aa2a05e24bc15ef4fa3 [file] [log] [blame]
Stephen Craned58bce02020-07-07 12:26:02 -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//! Included as a module in the binder crate internal tests for internal API
18//! access.
19
20use binder::declare_binder_interface;
21use binder::{
Stephen Cranef2735b42022-01-19 17:49:46 +000022 BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, SpIBinder, Status, StatusCode,
Stephen Craned58bce02020-07-07 12:26:02 -070023};
Stephen Cranef2735b42022-01-19 17:49:46 +000024// Import from impl API for testing only, should not be necessary as long as you
25// are using AIDL.
Matthew Maurere268a9f2022-07-26 09:31:30 -070026use binder::binder_impl::{Binder, BorrowedParcel, TransactionCode};
Stephen Craned58bce02020-07-07 12:26:02 -070027
28use std::ffi::{c_void, CStr, CString};
Stephen Craned58bce02020-07-07 12:26:02 -070029use std::sync::Once;
30
31#[allow(
32 non_camel_case_types,
33 non_snake_case,
34 non_upper_case_globals,
35 unused,
36 improper_ctypes,
37 missing_docs,
38 clippy::all
39)]
40mod bindings {
41 include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
42}
43
Stephen Crane1729e902021-02-15 11:05:43 -080044macro_rules! assert_eq {
45 ($left:expr, $right:expr $(,)?) => {
46 match (&$left, &$right) {
47 (left, right) => {
48 if *left != *right {
49 eprintln!(
50 "assertion failed: `{:?}` == `{:?}`, {}:{}:{}",
51 &*left,
52 &*right,
53 file!(),
54 line!(),
55 column!()
56 );
57 return Err(StatusCode::FAILED_TRANSACTION);
58 }
59 }
60 }
61 };
62}
63
64macro_rules! assert {
65 ($expr:expr) => {
66 if !$expr {
Matthew Maurere268a9f2022-07-26 09:31:30 -070067 eprintln!("assertion failed: `{:?}`, {}:{}:{}", $expr, file!(), line!(), column!());
Stephen Crane1729e902021-02-15 11:05:43 -080068 return Err(StatusCode::FAILED_TRANSACTION);
69 }
70 };
71}
72
Stephen Craned58bce02020-07-07 12:26:02 -070073static SERVICE_ONCE: Once = Once::new();
74static mut SERVICE: Option<SpIBinder> = None;
75
76/// Start binder service and return a raw AIBinder pointer to it.
77///
78/// Safe to call multiple times, only creates the service once.
79#[no_mangle]
80pub extern "C" fn rust_service() -> *mut c_void {
81 unsafe {
82 SERVICE_ONCE.call_once(|| {
Andrew Walbran88eca4f2021-04-13 14:26:01 +000083 SERVICE = Some(BnReadParcelTest::new_binder((), BinderFeatures::default()).as_binder());
Stephen Craned58bce02020-07-07 12:26:02 -070084 });
85 SERVICE.as_ref().unwrap().as_raw().cast()
86 }
87}
88
89/// Empty interface just to use the declare_binder_interface macro
90pub trait ReadParcelTest: Interface {}
91
92declare_binder_interface! {
93 ReadParcelTest["read_parcel_test"] {
94 native: BnReadParcelTest(on_transact),
95 proxy: BpReadParcelTest,
96 }
97}
98
99impl ReadParcelTest for Binder<BnReadParcelTest> {}
100
101impl ReadParcelTest for BpReadParcelTest {}
102
103impl ReadParcelTest for () {}
104
Stephen Craned58bce02020-07-07 12:26:02 -0700105#[allow(clippy::float_cmp)]
Andrew Walbran88eca4f2021-04-13 14:26:01 +0000106fn on_transact(
107 _service: &dyn ReadParcelTest,
108 code: TransactionCode,
Alice Ryhl8618c482021-11-09 15:35:35 +0000109 parcel: &BorrowedParcel<'_>,
110 reply: &mut BorrowedParcel<'_>,
Stephen Cranef2735b42022-01-19 17:49:46 +0000111) -> Result<(), StatusCode> {
Stephen Craned58bce02020-07-07 12:26:02 -0700112 match code {
113 bindings::Transaction_TEST_BOOL => {
Chris Wailese1f91f72022-04-19 17:26:39 -0700114 assert!(parcel.read::<bool>()?);
115 assert!(!parcel.read::<bool>()?);
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100116 // SAFETY: Just reading an extern constant.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700117 assert_eq!(parcel.read::<Vec<bool>>()?, unsafe { bindings::TESTDATA_BOOL });
Stephen Craned58bce02020-07-07 12:26:02 -0700118 assert_eq!(parcel.read::<Option<Vec<bool>>>()?, None);
119
120 reply.write(&true)?;
121 reply.write(&false)?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100122 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700123 reply.write(&unsafe { bindings::TESTDATA_BOOL }[..])?;
124 reply.write(&(None as Option<Vec<bool>>))?;
125 }
126 bindings::Transaction_TEST_BYTE => {
127 assert_eq!(parcel.read::<i8>()?, 0);
128 assert_eq!(parcel.read::<i8>()?, 1);
129 assert_eq!(parcel.read::<i8>()?, i8::max_value());
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100130 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700131 assert_eq!(parcel.read::<Vec<i8>>()?, unsafe { bindings::TESTDATA_I8 });
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100132 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700133 assert_eq!(parcel.read::<Vec<u8>>()?, unsafe { bindings::TESTDATA_U8 });
134 assert_eq!(parcel.read::<Option<Vec<i8>>>()?, None);
135
136 reply.write(&0i8)?;
137 reply.write(&1i8)?;
138 reply.write(&i8::max_value())?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100139 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700140 reply.write(&unsafe { bindings::TESTDATA_I8 }[..])?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100141 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700142 reply.write(&unsafe { bindings::TESTDATA_U8 }[..])?;
143 reply.write(&(None as Option<Vec<i8>>))?;
144 }
145 bindings::Transaction_TEST_U16 => {
146 assert_eq!(parcel.read::<u16>()?, 0);
147 assert_eq!(parcel.read::<u16>()?, 1);
148 assert_eq!(parcel.read::<u16>()?, u16::max_value());
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100149 // SAFETY: Just reading an extern constant.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700150 assert_eq!(parcel.read::<Vec<u16>>()?, unsafe { bindings::TESTDATA_CHARS });
Stephen Craned58bce02020-07-07 12:26:02 -0700151 assert_eq!(parcel.read::<Option<Vec<u16>>>()?, None);
152
153 reply.write(&0u16)?;
154 reply.write(&1u16)?;
155 reply.write(&u16::max_value())?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100156 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700157 reply.write(&unsafe { bindings::TESTDATA_CHARS }[..])?;
158 reply.write(&(None as Option<Vec<u16>>))?;
159 }
160 bindings::Transaction_TEST_I32 => {
161 assert_eq!(parcel.read::<i32>()?, 0);
162 assert_eq!(parcel.read::<i32>()?, 1);
163 assert_eq!(parcel.read::<i32>()?, i32::max_value());
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100164 // SAFETY: Just reading an extern constant.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700165 assert_eq!(parcel.read::<Vec<i32>>()?, unsafe { bindings::TESTDATA_I32 });
Stephen Craned58bce02020-07-07 12:26:02 -0700166 assert_eq!(parcel.read::<Option<Vec<i32>>>()?, None);
167
168 reply.write(&0i32)?;
169 reply.write(&1i32)?;
170 reply.write(&i32::max_value())?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100171 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700172 reply.write(&unsafe { bindings::TESTDATA_I32 }[..])?;
173 reply.write(&(None as Option<Vec<i32>>))?;
174 }
175 bindings::Transaction_TEST_I64 => {
176 assert_eq!(parcel.read::<i64>()?, 0);
177 assert_eq!(parcel.read::<i64>()?, 1);
178 assert_eq!(parcel.read::<i64>()?, i64::max_value());
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100179 // SAFETY: Just reading an extern constant.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700180 assert_eq!(parcel.read::<Vec<i64>>()?, unsafe { bindings::TESTDATA_I64 });
Stephen Craned58bce02020-07-07 12:26:02 -0700181 assert_eq!(parcel.read::<Option<Vec<i64>>>()?, None);
182
183 reply.write(&0i64)?;
184 reply.write(&1i64)?;
185 reply.write(&i64::max_value())?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100186 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700187 reply.write(&unsafe { bindings::TESTDATA_I64 }[..])?;
188 reply.write(&(None as Option<Vec<i64>>))?;
189 }
190 bindings::Transaction_TEST_U64 => {
191 assert_eq!(parcel.read::<u64>()?, 0);
192 assert_eq!(parcel.read::<u64>()?, 1);
193 assert_eq!(parcel.read::<u64>()?, u64::max_value());
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100194 // SAFETY: Just reading an extern constant.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700195 assert_eq!(parcel.read::<Vec<u64>>()?, unsafe { bindings::TESTDATA_U64 });
Stephen Craned58bce02020-07-07 12:26:02 -0700196 assert_eq!(parcel.read::<Option<Vec<u64>>>()?, None);
197
198 reply.write(&0u64)?;
199 reply.write(&1u64)?;
200 reply.write(&u64::max_value())?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100201 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700202 reply.write(&unsafe { bindings::TESTDATA_U64 }[..])?;
203 reply.write(&(None as Option<Vec<u64>>))?;
204 }
205 bindings::Transaction_TEST_F32 => {
206 assert_eq!(parcel.read::<f32>()?, 0f32);
207 let floats = parcel.read::<Vec<f32>>()?;
208 assert!(floats[0].is_nan());
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100209 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700210 assert_eq!(floats[1..], unsafe { bindings::TESTDATA_FLOAT }[1..]);
211 assert_eq!(parcel.read::<Option<Vec<f32>>>()?, None);
212
213 reply.write(&0f32)?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100214 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700215 reply.write(&unsafe { bindings::TESTDATA_FLOAT }[..])?;
216 reply.write(&(None as Option<Vec<f32>>))?;
217 }
218 bindings::Transaction_TEST_F64 => {
219 assert_eq!(parcel.read::<f64>()?, 0f64);
220 let doubles = parcel.read::<Vec<f64>>()?;
221 assert!(doubles[0].is_nan());
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100222 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700223 assert_eq!(doubles[1..], unsafe { bindings::TESTDATA_DOUBLE }[1..]);
224 assert_eq!(parcel.read::<Option<Vec<f64>>>()?, None);
225
226 reply.write(&0f64)?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100227 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700228 reply.write(&unsafe { bindings::TESTDATA_DOUBLE }[..])?;
229 reply.write(&(None as Option<Vec<f64>>))?;
230 }
231 bindings::Transaction_TEST_STRING => {
232 let s: Option<String> = parcel.read()?;
233 assert_eq!(s.as_deref(), Some("testing"));
234 let s: Option<String> = parcel.read()?;
235 assert_eq!(s, None);
236 let s: Option<Vec<Option<String>>> = parcel.read()?;
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100237 // SAFETY: Just reading an extern constant.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700238 for (s, expected) in s.unwrap().iter().zip(unsafe { bindings::TESTDATA_STRS }.iter()) {
239 let expected =
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100240 // SAFETY: Just reading an extern constant.
Matthew Maurere268a9f2022-07-26 09:31:30 -0700241 unsafe { expected.as_ref().and_then(|e| CStr::from_ptr(e).to_str().ok()) };
Stephen Craned58bce02020-07-07 12:26:02 -0700242 assert_eq!(s.as_deref(), expected);
243 }
244 let s: Option<Vec<Option<String>>> = parcel.read()?;
245 assert_eq!(s, None);
246
Andrew Walbran4ed9d772023-07-21 18:21:05 +0100247 // SAFETY: Just reading an extern constant.
Stephen Craned58bce02020-07-07 12:26:02 -0700248 let strings: Vec<Option<String>> = unsafe {
249 bindings::TESTDATA_STRS
250 .iter()
251 .map(|s| {
252 s.as_ref().map(|s| {
Matthew Maurere268a9f2022-07-26 09:31:30 -0700253 CStr::from_ptr(s).to_str().expect("String was not UTF-8").to_owned()
Stephen Craned58bce02020-07-07 12:26:02 -0700254 })
255 })
256 .collect()
257 };
258
259 reply.write("testing")?;
260 reply.write(&(None as Option<String>))?;
261 reply.write(&strings)?;
262 reply.write(&(None as Option<Vec<String>>))?;
263 }
264 bindings::Transaction_TEST_FILE_DESCRIPTOR => {
265 let file1 = parcel.read::<ParcelFileDescriptor>()?;
266 let file2 = parcel.read::<ParcelFileDescriptor>()?;
267 let files = parcel.read::<Vec<Option<ParcelFileDescriptor>>>()?;
268
269 reply.write(&file1)?;
270 reply.write(&file2)?;
271 reply.write(&files)?;
272 }
273 bindings::Transaction_TEST_IBINDER => {
274 assert!(parcel.read::<Option<SpIBinder>>()?.is_some());
275 assert!(parcel.read::<Option<SpIBinder>>()?.is_none());
276 let ibinders = parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.unwrap();
277 assert_eq!(ibinders.len(), 2);
278 assert!(ibinders[0].is_some());
279 assert!(ibinders[1].is_none());
280 assert!(parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.is_none());
281
Matthew Maurere268a9f2022-07-26 09:31:30 -0700282 let service =
283 unsafe { SERVICE.as_ref().expect("Global binder service not initialized").clone() };
Stephen Craned58bce02020-07-07 12:26:02 -0700284 reply.write(&service)?;
285 reply.write(&(None as Option<&SpIBinder>))?;
286 reply.write(&[Some(&service), None][..])?;
287 reply.write(&(None as Option<Vec<Option<&SpIBinder>>>))?;
288 }
289 bindings::Transaction_TEST_STATUS => {
290 let status: Status = parcel.read()?;
291 assert!(status.is_ok());
292 let status: Status = parcel.read()?;
293 assert_eq!(status.exception_code(), ExceptionCode::NULL_POINTER);
Matthew Maurere268a9f2022-07-26 09:31:30 -0700294 assert_eq!(status.get_description(), "Status(-4, EX_NULL_POINTER): 'a status message'");
Stephen Craned58bce02020-07-07 12:26:02 -0700295 let status: Status = parcel.read()?;
296 assert_eq!(status.service_specific_error(), 42);
297 assert_eq!(
298 status.get_description(),
299 "Status(-8, EX_SERVICE_SPECIFIC): '42: a service-specific error'"
300 );
301
302 reply.write(&Status::ok())?;
303 reply.write(&Status::new_exception(
304 ExceptionCode::NULL_POINTER,
305 Some(&CString::new("a status message").unwrap()),
306 ))?;
307 reply.write(&Status::new_service_specific_error(
308 42,
309 Some(&CString::new("a service-specific error").unwrap()),
310 ))?;
311 }
312 bindings::Transaction_TEST_FAIL => {
Stephen Crane1729e902021-02-15 11:05:43 -0800313 assert!(false);
Stephen Craned58bce02020-07-07 12:26:02 -0700314 }
315 _ => return Err(StatusCode::UNKNOWN_TRANSACTION),
316 }
317
318 assert_eq!(parcel.read::<i32>(), Err(StatusCode::NOT_ENOUGH_DATA));
319 Ok(())
320}