diff options
author | 2025-01-16 11:22:15 +0000 | |
---|---|---|
committer | 2025-01-16 11:52:44 +0000 | |
commit | eea659963337666325437dd67028d25deec48f87 (patch) | |
tree | 7ea67c2e5ed0e2a9b26aa58dba53cae3322906be | |
parent | cea15921073fbe96c2400f690b5fc164b34e3da1 (diff) |
Support Rust PersistableBundle in AIDL.
Bug: 389074518
Test: atest libbinder_rs-internal_test
Change-Id: I2ba487b6bd1ea18b2fc3eb331b1376cf20473408
-rw-r--r-- | aidl/binder/android/os/PersistableBundle.aidl | 2 | ||||
-rw-r--r-- | libs/binder/rust/src/persistable_bundle.rs | 46 |
2 files changed, 45 insertions, 3 deletions
diff --git a/aidl/binder/android/os/PersistableBundle.aidl b/aidl/binder/android/os/PersistableBundle.aidl index 248e9738df..9b11109262 100644 --- a/aidl/binder/android/os/PersistableBundle.aidl +++ b/aidl/binder/android/os/PersistableBundle.aidl @@ -17,4 +17,4 @@ package android.os; -@JavaOnlyStableParcelable @NdkOnlyStableParcelable parcelable PersistableBundle cpp_header "binder/PersistableBundle.h" ndk_header "android/persistable_bundle_aidl.h"; +@JavaOnlyStableParcelable @NdkOnlyStableParcelable @RustOnlyStableParcelable parcelable PersistableBundle cpp_header "binder/PersistableBundle.h" ndk_header "android/persistable_bundle_aidl.h" rust_type "binder::PersistableBundle"; diff --git a/libs/binder/rust/src/persistable_bundle.rs b/libs/binder/rust/src/persistable_bundle.rs index c62feb079e..1323d99e9a 100644 --- a/libs/binder/rust/src/persistable_bundle.rs +++ b/libs/binder/rust/src/persistable_bundle.rs @@ -14,11 +14,18 @@ * limitations under the License. */ +use crate::{ + binder::AsNative, + error::{status_result, StatusCode}, + impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable, + parcel::{BorrowedParcel, UnstructuredParcelable}, +}; use binder_ndk_sys::{ APersistableBundle, APersistableBundle_delete, APersistableBundle_dup, - APersistableBundle_isEqual, APersistableBundle_new, APersistableBundle_size, + APersistableBundle_isEqual, APersistableBundle_new, APersistableBundle_readFromParcel, + APersistableBundle_size, APersistableBundle_writeToParcel, }; -use std::ptr::NonNull; +use std::ptr::{null_mut, NonNull}; /// A mapping from string keys to values of various types. #[derive(Debug)] @@ -42,6 +49,13 @@ impl PersistableBundle { } } +// SAFETY: The underlying *APersistableBundle can be moved between threads. +unsafe impl Send for PersistableBundle {} + +// SAFETY: The underlying *APersistableBundle can be read from multiple threads, and we require +// `&mut PersistableBundle` for any operations which mutate it. +unsafe impl Sync for PersistableBundle {} + impl Default for PersistableBundle { fn default() -> Self { Self::new() @@ -73,6 +87,34 @@ impl PartialEq for PersistableBundle { } } +impl UnstructuredParcelable for PersistableBundle { + fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> { + let status = + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. `parcel.as_native_mut()` always returns a valid + // parcel pointer. + unsafe { APersistableBundle_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) }; + status_result(status) + } + + fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> { + let mut bundle = null_mut(); + + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. `parcel.as_native()` always returns a valid parcel + // pointer. + let status = unsafe { APersistableBundle_readFromParcel(parcel.as_native(), &mut bundle) }; + status_result(status)?; + + Ok(Self(NonNull::new(bundle).expect( + "APersistableBundle_readFromParcel returned success but didn't allocate bundle", + ))) + } +} + +impl_deserialize_for_unstructured_parcelable!(PersistableBundle); +impl_serialize_for_unstructured_parcelable!(PersistableBundle); + #[cfg(test)] mod test { use super::*; |