diff options
author | 2025-01-20 07:54:59 -0800 | |
---|---|---|
committer | 2025-01-20 07:54:59 -0800 | |
commit | ca725b1a0ee0db30b3b94a84d049feed4cd6f1f7 (patch) | |
tree | 5c8cb06404f20369f6b3e890cc9e7df8891a0cc3 | |
parent | bb8287d94648ac6567fcc9dac8d556b336a487a0 (diff) | |
parent | 19183730c838ea622b51e5e65adf9ac642264fe0 (diff) |
Merge changes I4dc1263b,Ie147ab00 into main am: 19183730c8
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/3452421
Change-Id: I7942a5c9463f84d39e0fd269ff9e043f274cab11
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | libs/binder/rust/src/persistable_bundle.rs | 275 |
1 files changed, 258 insertions, 17 deletions
diff --git a/libs/binder/rust/src/persistable_bundle.rs b/libs/binder/rust/src/persistable_bundle.rs index 58ea1380fb..367f334803 100644 --- a/libs/binder/rust/src/persistable_bundle.rs +++ b/libs/binder/rust/src/persistable_bundle.rs @@ -23,10 +23,14 @@ use crate::{ use binder_ndk_sys::{ APersistableBundle, APersistableBundle_delete, APersistableBundle_dup, APersistableBundle_erase, APersistableBundle_getBoolean, APersistableBundle_getDouble, - APersistableBundle_getInt, APersistableBundle_getLong, APersistableBundle_isEqual, - APersistableBundle_new, APersistableBundle_putBoolean, APersistableBundle_putDouble, - APersistableBundle_putInt, APersistableBundle_putLong, APersistableBundle_readFromParcel, - APersistableBundle_size, APersistableBundle_writeToParcel, + APersistableBundle_getInt, APersistableBundle_getLong, APersistableBundle_getPersistableBundle, + APersistableBundle_isEqual, APersistableBundle_new, APersistableBundle_putBoolean, + APersistableBundle_putBooleanVector, APersistableBundle_putDouble, + APersistableBundle_putDoubleVector, APersistableBundle_putInt, APersistableBundle_putIntVector, + APersistableBundle_putLong, APersistableBundle_putLongVector, + APersistableBundle_putPersistableBundle, APersistableBundle_putString, + APersistableBundle_putStringVector, APersistableBundle_readFromParcel, APersistableBundle_size, + APersistableBundle_writeToParcel, }; use std::ffi::{CString, NulError}; use std::ptr::{null_mut, NonNull}; @@ -60,7 +64,7 @@ impl PersistableBundle { let key = CString::new(key)?; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. + // to be valid for the duration of this call. Ok(unsafe { APersistableBundle_erase(self.0.as_ptr(), key.as_ptr()) != 0 }) } @@ -73,7 +77,7 @@ impl PersistableBundle { let key = CString::new(key)?; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. + // to be valid for the duration of this call. unsafe { APersistableBundle_putBoolean(self.0.as_ptr(), key.as_ptr(), value); } @@ -89,7 +93,7 @@ impl PersistableBundle { let key = CString::new(key)?; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. + // to be valid for the duration of this call. unsafe { APersistableBundle_putInt(self.0.as_ptr(), key.as_ptr(), value); } @@ -105,7 +109,7 @@ impl PersistableBundle { let key = CString::new(key)?; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. + // to be valid for the duration of this call. unsafe { APersistableBundle_putLong(self.0.as_ptr(), key.as_ptr(), value); } @@ -121,13 +125,182 @@ impl PersistableBundle { let key = CString::new(key)?; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. + // to be valid for the duration of this call. unsafe { APersistableBundle_putDouble(self.0.as_ptr(), key.as_ptr(), value); } Ok(()) } + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key or value contains a NUL character. + pub fn insert_string(&mut self, key: &str, value: &str) -> Result<(), NulError> { + let key = CString::new(key)?; + let value = CString::new(value)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `CStr::as_ptr` is guaranteed + // to be valid for the duration of this call. + unsafe { + APersistableBundle_putString(self.0.as_ptr(), key.as_ptr(), value.as_ptr()); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_bool_vec(&mut self, key: &str, value: &[bool]) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putBooleanVector( + self.0.as_ptr(), + key.as_ptr(), + value.as_ptr(), + value.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_int_vec(&mut self, key: &str, value: &[i32]) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putIntVector( + self.0.as_ptr(), + key.as_ptr(), + value.as_ptr(), + value.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_long_vec(&mut self, key: &str, value: &[i64]) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putLongVector( + self.0.as_ptr(), + key.as_ptr(), + value.as_ptr(), + value.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_double_vec(&mut self, key: &str, value: &[f64]) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putDoubleVector( + self.0.as_ptr(), + key.as_ptr(), + value.as_ptr(), + value.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_string_vec<'a, T: ToString + 'a>( + &mut self, + key: &str, + value: impl IntoIterator<Item = &'a T>, + ) -> Result<(), NulError> { + let key = CString::new(key)?; + // We need to collect the new `CString`s into something first so that they live long enough + // for their pointers to be valid for the `APersistableBundle_putStringVector` call below. + let c_strings = value + .into_iter() + .map(|s| CString::new(s.to_string())) + .collect::<Result<Vec<_>, NulError>>()?; + let char_pointers = c_strings.iter().map(|s| s.as_ptr()).collect::<Vec<_>>(); + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the duration of this call, and likewise the pointer returned by + // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the + // duration of the call. + unsafe { + APersistableBundle_putStringVector( + self.0.as_ptr(), + key.as_ptr(), + char_pointers.as_ptr(), + char_pointers.len().try_into().unwrap(), + ); + } + Ok(()) + } + + /// Inserts a key-value pair into the bundle. + /// + /// If the key is already present then its value will be overwritten by the given value. + /// + /// Returns an error if the key contains a NUL character. + pub fn insert_persistable_bundle( + &mut self, + key: &str, + value: &PersistableBundle, + ) -> Result<(), NulError> { + let key = CString::new(key)?; + // SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the + // lifetime of the `PersistableBundle`s. The pointer returned by `CStr::as_ptr` is + // guaranteed to be valid for the duration of this call, and + // `APersistableBundle_putPersistableBundle` does a deep copy so that is all that is + // required. + unsafe { + APersistableBundle_putPersistableBundle( + self.0.as_ptr(), + key.as_ptr(), + value.0.as_ptr(), + ); + } + Ok(()) + } + /// Gets the boolean value associated with the given key. /// /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist @@ -137,8 +310,8 @@ impl PersistableBundle { let mut value = false; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. The value pointer must be valid because it comes - // from a reference. + // to be valid for the duration of this call. The value pointer must be valid because it + // comes from a reference. if unsafe { APersistableBundle_getBoolean(self.0.as_ptr(), key.as_ptr(), &mut value) } { Ok(Some(value)) } else { @@ -155,8 +328,8 @@ impl PersistableBundle { let mut value = 0; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. The value pointer must be valid because it comes - // from a reference. + // to be valid for the duration of this call. The value pointer must be valid because it + // comes from a reference. if unsafe { APersistableBundle_getInt(self.0.as_ptr(), key.as_ptr(), &mut value) } { Ok(Some(value)) } else { @@ -173,8 +346,8 @@ impl PersistableBundle { let mut value = 0; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. The value pointer must be valid because it comes - // from a reference. + // to be valid for the duration of this call. The value pointer must be valid because it + // comes from a reference. if unsafe { APersistableBundle_getLong(self.0.as_ptr(), key.as_ptr(), &mut value) } { Ok(Some(value)) } else { @@ -191,14 +364,36 @@ impl PersistableBundle { let mut value = 0.0; // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed - // to be valid for the lifetime of `key`. The value pointer must be valid because it comes - // from a reference. + // to be valid for the duration of this call. The value pointer must be valid because it + // comes from a reference. if unsafe { APersistableBundle_getDouble(self.0.as_ptr(), key.as_ptr(), &mut value) } { Ok(Some(value)) } else { Ok(None) } } + + /// Gets the `PersistableBundle` value associated with the given key. + /// + /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist + /// in the bundle. + pub fn get_persistable_bundle(&self, key: &str) -> Result<Option<Self>, NulError> { + let key = CString::new(key)?; + let mut value = null_mut(); + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed + // to be valid for the lifetime of `key`. The value pointer must be valid because it comes + // from a reference. + if unsafe { + APersistableBundle_getPersistableBundle(self.0.as_ptr(), key.as_ptr(), &mut value) + } { + Ok(Some(Self(NonNull::new(value).expect( + "APersistableBundle_getPersistableBundle returned true but didn't set outBundle", + )))) + } else { + Ok(None) + } + } } // SAFETY: The underlying *APersistableBundle can be moved between threads. @@ -339,4 +534,50 @@ mod test { assert_eq!(bundle.get_double("double"), Ok(None)); assert_eq!(bundle.size(), 0); } + + #[test] + fn insert_string() { + let mut bundle = PersistableBundle::new(); + assert_eq!(bundle.insert_string("string", "foo"), Ok(())); + assert_eq!(bundle.size(), 1); + } + + #[test] + fn insert_vec() { + let mut bundle = PersistableBundle::new(); + + assert_eq!(bundle.insert_bool_vec("bool", &[]), Ok(())); + assert_eq!(bundle.insert_int_vec("int", &[42]), Ok(())); + assert_eq!(bundle.insert_long_vec("long", &[66, 67, 68]), Ok(())); + assert_eq!(bundle.insert_double_vec("double", &[123.4]), Ok(())); + assert_eq!(bundle.insert_string_vec("string", &["foo", "bar", "baz"]), Ok(())); + assert_eq!( + bundle.insert_string_vec( + "string", + &[&"foo".to_string(), &"bar".to_string(), &"baz".to_string()] + ), + Ok(()) + ); + assert_eq!( + bundle.insert_string_vec( + "string", + &["foo".to_string(), "bar".to_string(), "baz".to_string()] + ), + Ok(()) + ); + + assert_eq!(bundle.size(), 5); + } + + #[test] + fn insert_get_bundle() { + let mut bundle = PersistableBundle::new(); + + let mut sub_bundle = PersistableBundle::new(); + assert_eq!(sub_bundle.insert_int("int", 42), Ok(())); + assert_eq!(sub_bundle.size(), 1); + assert_eq!(bundle.insert_persistable_bundle("bundle", &sub_bundle), Ok(())); + + assert_eq!(bundle.get_persistable_bundle("bundle"), Ok(Some(sub_bundle))); + } } |