summaryrefslogtreecommitdiff
path: root/libs/binder/rust/tests/serialization.rs
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder/rust/tests/serialization.rs')
-rw-r--r--libs/binder/rust/tests/serialization.rs331
1 files changed, 0 insertions, 331 deletions
diff --git a/libs/binder/rust/tests/serialization.rs b/libs/binder/rust/tests/serialization.rs
deleted file mode 100644
index 66ba846c2d..0000000000
--- a/libs/binder/rust/tests/serialization.rs
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//! Included as a module in the binder crate internal tests for internal API
-//! access.
-
-use binder::declare_binder_interface;
-use binder::parcel::ParcelFileDescriptor;
-use binder::{
- Binder, BinderFeatures, ExceptionCode, Interface, Parcel, Result, SpIBinder, Status,
- StatusCode, TransactionCode,
-};
-
-use std::ffi::{c_void, CStr, CString};
-use std::sync::Once;
-
-#[allow(
- non_camel_case_types,
- non_snake_case,
- non_upper_case_globals,
- unused,
- improper_ctypes,
- missing_docs,
- clippy::all
-)]
-mod bindings {
- include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
-}
-
-macro_rules! assert_eq {
- ($left:expr, $right:expr $(,)?) => {
- match (&$left, &$right) {
- (left, right) => {
- if *left != *right {
- eprintln!(
- "assertion failed: `{:?}` == `{:?}`, {}:{}:{}",
- &*left,
- &*right,
- file!(),
- line!(),
- column!()
- );
- return Err(StatusCode::FAILED_TRANSACTION);
- }
- }
- }
- };
-}
-
-macro_rules! assert {
- ($expr:expr) => {
- if !$expr {
- eprintln!(
- "assertion failed: `{:?}`, {}:{}:{}",
- $expr,
- file!(),
- line!(),
- column!()
- );
- return Err(StatusCode::FAILED_TRANSACTION);
- }
- };
-}
-
-static SERVICE_ONCE: Once = Once::new();
-static mut SERVICE: Option<SpIBinder> = None;
-
-/// Start binder service and return a raw AIBinder pointer to it.
-///
-/// Safe to call multiple times, only creates the service once.
-#[no_mangle]
-pub extern "C" fn rust_service() -> *mut c_void {
- unsafe {
- SERVICE_ONCE.call_once(|| {
- SERVICE = Some(BnReadParcelTest::new_binder((), BinderFeatures::default()).as_binder());
- });
- SERVICE.as_ref().unwrap().as_raw().cast()
- }
-}
-
-/// Empty interface just to use the declare_binder_interface macro
-pub trait ReadParcelTest: Interface {}
-
-declare_binder_interface! {
- ReadParcelTest["read_parcel_test"] {
- native: BnReadParcelTest(on_transact),
- proxy: BpReadParcelTest,
- }
-}
-
-impl ReadParcelTest for Binder<BnReadParcelTest> {}
-
-impl ReadParcelTest for BpReadParcelTest {}
-
-impl ReadParcelTest for () {}
-
-#[allow(clippy::float_cmp)]
-fn on_transact(
- _service: &dyn ReadParcelTest,
- code: TransactionCode,
- parcel: &Parcel,
- reply: &mut Parcel,
-) -> Result<()> {
- match code {
- bindings::Transaction_TEST_BOOL => {
- assert_eq!(parcel.read::<bool>()?, true);
- assert_eq!(parcel.read::<bool>()?, false);
- assert_eq!(parcel.read::<Vec<bool>>()?, unsafe {
- bindings::TESTDATA_BOOL
- });
- assert_eq!(parcel.read::<Option<Vec<bool>>>()?, None);
-
- reply.write(&true)?;
- reply.write(&false)?;
- reply.write(&unsafe { bindings::TESTDATA_BOOL }[..])?;
- reply.write(&(None as Option<Vec<bool>>))?;
- }
- bindings::Transaction_TEST_BYTE => {
- assert_eq!(parcel.read::<i8>()?, 0);
- assert_eq!(parcel.read::<i8>()?, 1);
- assert_eq!(parcel.read::<i8>()?, i8::max_value());
- assert_eq!(parcel.read::<Vec<i8>>()?, unsafe { bindings::TESTDATA_I8 });
- assert_eq!(parcel.read::<Vec<u8>>()?, unsafe { bindings::TESTDATA_U8 });
- assert_eq!(parcel.read::<Option<Vec<i8>>>()?, None);
-
- reply.write(&0i8)?;
- reply.write(&1i8)?;
- reply.write(&i8::max_value())?;
- reply.write(&unsafe { bindings::TESTDATA_I8 }[..])?;
- reply.write(&unsafe { bindings::TESTDATA_U8 }[..])?;
- reply.write(&(None as Option<Vec<i8>>))?;
- }
- bindings::Transaction_TEST_U16 => {
- assert_eq!(parcel.read::<u16>()?, 0);
- assert_eq!(parcel.read::<u16>()?, 1);
- assert_eq!(parcel.read::<u16>()?, u16::max_value());
- assert_eq!(parcel.read::<Vec<u16>>()?, unsafe {
- bindings::TESTDATA_CHARS
- });
- assert_eq!(parcel.read::<Option<Vec<u16>>>()?, None);
-
- reply.write(&0u16)?;
- reply.write(&1u16)?;
- reply.write(&u16::max_value())?;
- reply.write(&unsafe { bindings::TESTDATA_CHARS }[..])?;
- reply.write(&(None as Option<Vec<u16>>))?;
- }
- bindings::Transaction_TEST_I32 => {
- assert_eq!(parcel.read::<i32>()?, 0);
- assert_eq!(parcel.read::<i32>()?, 1);
- assert_eq!(parcel.read::<i32>()?, i32::max_value());
- assert_eq!(parcel.read::<Vec<i32>>()?, unsafe {
- bindings::TESTDATA_I32
- });
- assert_eq!(parcel.read::<Option<Vec<i32>>>()?, None);
-
- reply.write(&0i32)?;
- reply.write(&1i32)?;
- reply.write(&i32::max_value())?;
- reply.write(&unsafe { bindings::TESTDATA_I32 }[..])?;
- reply.write(&(None as Option<Vec<i32>>))?;
- }
- bindings::Transaction_TEST_I64 => {
- assert_eq!(parcel.read::<i64>()?, 0);
- assert_eq!(parcel.read::<i64>()?, 1);
- assert_eq!(parcel.read::<i64>()?, i64::max_value());
- assert_eq!(parcel.read::<Vec<i64>>()?, unsafe {
- bindings::TESTDATA_I64
- });
- assert_eq!(parcel.read::<Option<Vec<i64>>>()?, None);
-
- reply.write(&0i64)?;
- reply.write(&1i64)?;
- reply.write(&i64::max_value())?;
- reply.write(&unsafe { bindings::TESTDATA_I64 }[..])?;
- reply.write(&(None as Option<Vec<i64>>))?;
- }
- bindings::Transaction_TEST_U64 => {
- assert_eq!(parcel.read::<u64>()?, 0);
- assert_eq!(parcel.read::<u64>()?, 1);
- assert_eq!(parcel.read::<u64>()?, u64::max_value());
- assert_eq!(parcel.read::<Vec<u64>>()?, unsafe {
- bindings::TESTDATA_U64
- });
- assert_eq!(parcel.read::<Option<Vec<u64>>>()?, None);
-
- reply.write(&0u64)?;
- reply.write(&1u64)?;
- reply.write(&u64::max_value())?;
- reply.write(&unsafe { bindings::TESTDATA_U64 }[..])?;
- reply.write(&(None as Option<Vec<u64>>))?;
- }
- bindings::Transaction_TEST_F32 => {
- assert_eq!(parcel.read::<f32>()?, 0f32);
- let floats = parcel.read::<Vec<f32>>()?;
- assert!(floats[0].is_nan());
- assert_eq!(floats[1..], unsafe { bindings::TESTDATA_FLOAT }[1..]);
- assert_eq!(parcel.read::<Option<Vec<f32>>>()?, None);
-
- reply.write(&0f32)?;
- reply.write(&unsafe { bindings::TESTDATA_FLOAT }[..])?;
- reply.write(&(None as Option<Vec<f32>>))?;
- }
- bindings::Transaction_TEST_F64 => {
- assert_eq!(parcel.read::<f64>()?, 0f64);
- let doubles = parcel.read::<Vec<f64>>()?;
- assert!(doubles[0].is_nan());
- assert_eq!(doubles[1..], unsafe { bindings::TESTDATA_DOUBLE }[1..]);
- assert_eq!(parcel.read::<Option<Vec<f64>>>()?, None);
-
- reply.write(&0f64)?;
- reply.write(&unsafe { bindings::TESTDATA_DOUBLE }[..])?;
- reply.write(&(None as Option<Vec<f64>>))?;
- }
- bindings::Transaction_TEST_STRING => {
- let s: Option<String> = parcel.read()?;
- assert_eq!(s.as_deref(), Some("testing"));
- let s: Option<String> = parcel.read()?;
- assert_eq!(s, None);
- let s: Option<Vec<Option<String>>> = parcel.read()?;
- for (s, expected) in s
- .unwrap()
- .iter()
- .zip(unsafe { bindings::TESTDATA_STRS }.iter())
- {
- let expected = unsafe {
- expected
- .as_ref()
- .and_then(|e| CStr::from_ptr(e).to_str().ok())
- };
- assert_eq!(s.as_deref(), expected);
- }
- let s: Option<Vec<Option<String>>> = parcel.read()?;
- assert_eq!(s, None);
-
- let strings: Vec<Option<String>> = unsafe {
- bindings::TESTDATA_STRS
- .iter()
- .map(|s| {
- s.as_ref().map(|s| {
- CStr::from_ptr(s)
- .to_str()
- .expect("String was not UTF-8")
- .to_owned()
- })
- })
- .collect()
- };
-
- reply.write("testing")?;
- reply.write(&(None as Option<String>))?;
- reply.write(&strings)?;
- reply.write(&(None as Option<Vec<String>>))?;
- }
- bindings::Transaction_TEST_FILE_DESCRIPTOR => {
- let file1 = parcel.read::<ParcelFileDescriptor>()?;
- let file2 = parcel.read::<ParcelFileDescriptor>()?;
- let files = parcel.read::<Vec<Option<ParcelFileDescriptor>>>()?;
-
- reply.write(&file1)?;
- reply.write(&file2)?;
- reply.write(&files)?;
- }
- bindings::Transaction_TEST_IBINDER => {
- assert!(parcel.read::<Option<SpIBinder>>()?.is_some());
- assert!(parcel.read::<Option<SpIBinder>>()?.is_none());
- let ibinders = parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.unwrap();
- assert_eq!(ibinders.len(), 2);
- assert!(ibinders[0].is_some());
- assert!(ibinders[1].is_none());
- assert!(parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.is_none());
-
- let service = unsafe {
- SERVICE
- .as_ref()
- .expect("Global binder service not initialized")
- .clone()
- };
- reply.write(&service)?;
- reply.write(&(None as Option<&SpIBinder>))?;
- reply.write(&[Some(&service), None][..])?;
- reply.write(&(None as Option<Vec<Option<&SpIBinder>>>))?;
- }
- bindings::Transaction_TEST_STATUS => {
- let status: Status = parcel.read()?;
- assert!(status.is_ok());
- let status: Status = parcel.read()?;
- assert_eq!(status.exception_code(), ExceptionCode::NULL_POINTER);
- assert_eq!(
- status.get_description(),
- "Status(-4, EX_NULL_POINTER): 'a status message'"
- );
- let status: Status = parcel.read()?;
- assert_eq!(status.service_specific_error(), 42);
- assert_eq!(
- status.get_description(),
- "Status(-8, EX_SERVICE_SPECIFIC): '42: a service-specific error'"
- );
-
- reply.write(&Status::ok())?;
- reply.write(&Status::new_exception(
- ExceptionCode::NULL_POINTER,
- Some(&CString::new("a status message").unwrap()),
- ))?;
- reply.write(&Status::new_service_specific_error(
- 42,
- Some(&CString::new("a service-specific error").unwrap()),
- ))?;
- }
- bindings::Transaction_TEST_FAIL => {
- assert!(false);
- }
- _ => return Err(StatusCode::UNKNOWN_TRANSACTION),
- }
-
- assert_eq!(parcel.read::<i32>(), Err(StatusCode::NOT_ENOUGH_DATA));
- Ok(())
-}