Skip to content

Commit eea6599

Browse files
committed
Support Rust PersistableBundle in AIDL.
Bug: 389074518 Test: atest libbinder_rs-internal_test Change-Id: I2ba487b6bd1ea18b2fc3eb331b1376cf20473408
1 parent cea1592 commit eea6599

2 files changed

Lines changed: 45 additions & 3 deletions

File tree

aidl/binder/android/os/PersistableBundle.aidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717

1818
package android.os;
1919

20-
@JavaOnlyStableParcelable @NdkOnlyStableParcelable parcelable PersistableBundle cpp_header "binder/PersistableBundle.h" ndk_header "android/persistable_bundle_aidl.h";
20+
@JavaOnlyStableParcelable @NdkOnlyStableParcelable @RustOnlyStableParcelable parcelable PersistableBundle cpp_header "binder/PersistableBundle.h" ndk_header "android/persistable_bundle_aidl.h" rust_type "binder::PersistableBundle";

libs/binder/rust/src/persistable_bundle.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,18 @@
1414
* limitations under the License.
1515
*/
1616

17+
use crate::{
18+
binder::AsNative,
19+
error::{status_result, StatusCode},
20+
impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable,
21+
parcel::{BorrowedParcel, UnstructuredParcelable},
22+
};
1723
use binder_ndk_sys::{
1824
APersistableBundle, APersistableBundle_delete, APersistableBundle_dup,
19-
APersistableBundle_isEqual, APersistableBundle_new, APersistableBundle_size,
25+
APersistableBundle_isEqual, APersistableBundle_new, APersistableBundle_readFromParcel,
26+
APersistableBundle_size, APersistableBundle_writeToParcel,
2027
};
21-
use std::ptr::NonNull;
28+
use std::ptr::{null_mut, NonNull};
2229

2330
/// A mapping from string keys to values of various types.
2431
#[derive(Debug)]
@@ -42,6 +49,13 @@ impl PersistableBundle {
4249
}
4350
}
4451

52+
// SAFETY: The underlying *APersistableBundle can be moved between threads.
53+
unsafe impl Send for PersistableBundle {}
54+
55+
// SAFETY: The underlying *APersistableBundle can be read from multiple threads, and we require
56+
// `&mut PersistableBundle` for any operations which mutate it.
57+
unsafe impl Sync for PersistableBundle {}
58+
4559
impl Default for PersistableBundle {
4660
fn default() -> Self {
4761
Self::new()
@@ -73,6 +87,34 @@ impl PartialEq for PersistableBundle {
7387
}
7488
}
7589

90+
impl UnstructuredParcelable for PersistableBundle {
91+
fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
92+
let status =
93+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
94+
// lifetime of the `PersistableBundle`. `parcel.as_native_mut()` always returns a valid
95+
// parcel pointer.
96+
unsafe { APersistableBundle_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) };
97+
status_result(status)
98+
}
99+
100+
fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
101+
let mut bundle = null_mut();
102+
103+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
104+
// lifetime of the `PersistableBundle`. `parcel.as_native()` always returns a valid parcel
105+
// pointer.
106+
let status = unsafe { APersistableBundle_readFromParcel(parcel.as_native(), &mut bundle) };
107+
status_result(status)?;
108+
109+
Ok(Self(NonNull::new(bundle).expect(
110+
"APersistableBundle_readFromParcel returned success but didn't allocate bundle",
111+
)))
112+
}
113+
}
114+
115+
impl_deserialize_for_unstructured_parcelable!(PersistableBundle);
116+
impl_serialize_for_unstructured_parcelable!(PersistableBundle);
117+
76118
#[cfg(test)]
77119
mod test {
78120
use super::*;

0 commit comments

Comments
 (0)