Skip to content

Commit ca340b1

Browse files
Treehugger RobotGerrit Code Review
authored andcommitted
Merge changes from topic "unstructured_parcelable_macros" into main
* changes: Add optional method to read into existing unstructured parcelable. Add UnstructuredParcelable trait and macros.
2 parents 743aab2 + b755fa5 commit ca340b1

4 files changed

Lines changed: 180 additions & 75 deletions

File tree

libs/binder/rust/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ pub mod binder_impl {
136136
pub use crate::native::Binder;
137137
pub use crate::parcel::{
138138
BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Parcel,
139-
ParcelableMetadata, Serialize, SerializeArray, SerializeOption, NON_NULL_PARCELABLE_FLAG,
140-
NULL_PARCELABLE_FLAG,
139+
ParcelableMetadata, Serialize, SerializeArray, SerializeOption, UnstructuredParcelable,
140+
NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG,
141141
};
142142
pub use crate::proxy::{AssociateClass, Proxy};
143143
}

libs/binder/rust/src/parcel.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mod parcelable_holder;
3434
pub use self::file_descriptor::ParcelFileDescriptor;
3535
pub use self::parcelable::{
3636
Deserialize, DeserializeArray, DeserializeOption, Parcelable, Serialize, SerializeArray,
37-
SerializeOption, NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG,
37+
SerializeOption, UnstructuredParcelable, NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG,
3838
};
3939
pub use self::parcelable_holder::{ParcelableHolder, ParcelableMetadata};
4040

libs/binder/rust/src/parcel/parcelable.rs

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use std::os::raw::c_char;
2727
use std::ptr;
2828
use std::slice;
2929

30-
/// Super-trait for Binder parcelables.
30+
/// Super-trait for structured Binder parcelables, i.e. those generated from AIDL.
3131
///
3232
/// This trait is equivalent `android::Parcelable` in C++,
3333
/// and defines a common interface that all parcelables need
@@ -50,6 +50,35 @@ pub trait Parcelable {
5050
fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()>;
5151
}
5252

53+
/// Super-trait for unstructured Binder parcelables, i.e. those implemented manually.
54+
///
55+
/// These differ from structured parcelables in that they may not have a reasonable default value
56+
/// and so aren't required to implement `Default`.
57+
pub trait UnstructuredParcelable: Sized {
58+
/// Internal serialization function for parcelables.
59+
///
60+
/// This method is mainly for internal use. `Serialize::serialize` and its variants are
61+
/// generally preferred over calling this function, since the former also prepend a header.
62+
fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>;
63+
64+
/// Internal deserialization function for parcelables.
65+
///
66+
/// This method is mainly for internal use. `Deserialize::deserialize` and its variants are
67+
/// generally preferred over calling this function, since the former also parse the additional
68+
/// header.
69+
fn from_parcel(parcel: &BorrowedParcel<'_>) -> Result<Self>;
70+
71+
/// Internal deserialization function for parcelables.
72+
///
73+
/// This method is mainly for internal use. `Deserialize::deserialize_from` and its variants are
74+
/// generally preferred over calling this function, since the former also parse the additional
75+
/// header.
76+
fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> {
77+
*self = Self::from_parcel(parcel)?;
78+
Ok(())
79+
}
80+
}
81+
5382
/// A struct whose instances can be written to a [`crate::parcel::Parcel`].
5483
// Might be able to hook this up as a serde backend in the future?
5584
pub trait Serialize {
@@ -1002,6 +1031,125 @@ macro_rules! impl_deserialize_for_parcelable {
10021031
};
10031032
}
10041033

1034+
/// Implements `Serialize` trait and friends for an unstructured parcelable.
1035+
///
1036+
/// The target type must implement the `UnstructuredParcelable` trait.
1037+
#[macro_export]
1038+
macro_rules! impl_serialize_for_unstructured_parcelable {
1039+
($parcelable:ident) => {
1040+
$crate::impl_serialize_for_unstructured_parcelable!($parcelable < >);
1041+
};
1042+
($parcelable:ident < $( $param:ident ),* , >) => {
1043+
$crate::impl_serialize_for_unstructured_parcelable!($parcelable < $($param),* >);
1044+
};
1045+
($parcelable:ident < $( $param:ident ),* > ) => {
1046+
impl < $($param),* > $crate::binder_impl::Serialize for $parcelable < $($param),* > {
1047+
fn serialize(
1048+
&self,
1049+
parcel: &mut $crate::binder_impl::BorrowedParcel<'_>,
1050+
) -> std::result::Result<(), $crate::StatusCode> {
1051+
<Self as $crate::binder_impl::SerializeOption>::serialize_option(Some(self), parcel)
1052+
}
1053+
}
1054+
1055+
impl < $($param),* > $crate::binder_impl::SerializeArray for $parcelable < $($param),* > {}
1056+
1057+
impl < $($param),* > $crate::binder_impl::SerializeOption for $parcelable < $($param),* > {
1058+
fn serialize_option(
1059+
this: Option<&Self>,
1060+
parcel: &mut $crate::binder_impl::BorrowedParcel<'_>,
1061+
) -> std::result::Result<(), $crate::StatusCode> {
1062+
if let Some(this) = this {
1063+
use $crate::binder_impl::UnstructuredParcelable;
1064+
parcel.write(&$crate::binder_impl::NON_NULL_PARCELABLE_FLAG)?;
1065+
this.write_to_parcel(parcel)
1066+
} else {
1067+
parcel.write(&$crate::binder_impl::NULL_PARCELABLE_FLAG)
1068+
}
1069+
}
1070+
}
1071+
};
1072+
}
1073+
1074+
/// Implement `Deserialize` trait and friends for an unstructured parcelable
1075+
///
1076+
/// The target type must implement the `UnstructuredParcelable` trait.
1077+
#[macro_export]
1078+
macro_rules! impl_deserialize_for_unstructured_parcelable {
1079+
($parcelable:ident) => {
1080+
$crate::impl_deserialize_for_unstructured_parcelable!($parcelable < >);
1081+
};
1082+
($parcelable:ident < $( $param:ident ),* , >) => {
1083+
$crate::impl_deserialize_for_unstructured_parcelable!($parcelable < $($param),* >);
1084+
};
1085+
($parcelable:ident < $( $param:ident ),* > ) => {
1086+
impl < $($param: Default),* > $crate::binder_impl::Deserialize for $parcelable < $($param),* > {
1087+
type UninitType = Option<Self>;
1088+
fn uninit() -> Self::UninitType { None }
1089+
fn from_init(value: Self) -> Self::UninitType { Some(value) }
1090+
fn deserialize(
1091+
parcel: &$crate::binder_impl::BorrowedParcel<'_>,
1092+
) -> std::result::Result<Self, $crate::StatusCode> {
1093+
$crate::binder_impl::DeserializeOption::deserialize_option(parcel)
1094+
.transpose()
1095+
.unwrap_or(Err($crate::StatusCode::UNEXPECTED_NULL))
1096+
}
1097+
fn deserialize_from(
1098+
&mut self,
1099+
parcel: &$crate::binder_impl::BorrowedParcel<'_>,
1100+
) -> std::result::Result<(), $crate::StatusCode> {
1101+
let status: i32 = parcel.read()?;
1102+
if status == $crate::binder_impl::NULL_PARCELABLE_FLAG {
1103+
Err($crate::StatusCode::UNEXPECTED_NULL)
1104+
} else {
1105+
use $crate::binder_impl::UnstructuredParcelable;
1106+
self.read_from_parcel(parcel)
1107+
}
1108+
}
1109+
}
1110+
1111+
impl < $($param: Default),* > $crate::binder_impl::DeserializeArray for $parcelable < $($param),* > {}
1112+
1113+
impl < $($param: Default),* > $crate::binder_impl::DeserializeOption for $parcelable < $($param),* > {
1114+
fn deserialize_option(
1115+
parcel: &$crate::binder_impl::BorrowedParcel<'_>,
1116+
) -> std::result::Result<Option<Self>, $crate::StatusCode> {
1117+
let present: i32 = parcel.read()?;
1118+
match present {
1119+
$crate::binder_impl::NULL_PARCELABLE_FLAG => Ok(None),
1120+
$crate::binder_impl::NON_NULL_PARCELABLE_FLAG => {
1121+
use $crate::binder_impl::UnstructuredParcelable;
1122+
Ok(Some(Self::from_parcel(parcel)?))
1123+
}
1124+
_ => Err(StatusCode::BAD_VALUE),
1125+
}
1126+
}
1127+
fn deserialize_option_from(
1128+
this: &mut Option<Self>,
1129+
parcel: &$crate::binder_impl::BorrowedParcel<'_>,
1130+
) -> std::result::Result<(), $crate::StatusCode> {
1131+
let present: i32 = parcel.read()?;
1132+
match present {
1133+
$crate::binder_impl::NULL_PARCELABLE_FLAG => {
1134+
*this = None;
1135+
Ok(())
1136+
}
1137+
$crate::binder_impl::NON_NULL_PARCELABLE_FLAG => {
1138+
use $crate::binder_impl::UnstructuredParcelable;
1139+
if let Some(this) = this {
1140+
this.read_from_parcel(parcel)?;
1141+
} else {
1142+
*this = Some(Self::from_parcel(parcel)?);
1143+
}
1144+
Ok(())
1145+
}
1146+
_ => Err(StatusCode::BAD_VALUE),
1147+
}
1148+
}
1149+
}
1150+
};
1151+
}
1152+
10051153
impl<T: Serialize> Serialize for Box<T> {
10061154
fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
10071155
Serialize::serialize(&**self, parcel)

libs/nativewindow/rust/src/lib.rs

Lines changed: 28 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ extern crate nativewindow_bindgen as ffi;
1919
pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
2020

2121
use binder::{
22-
binder_impl::{
23-
BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Serialize,
24-
SerializeArray, SerializeOption, NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG,
25-
},
22+
binder_impl::{BorrowedParcel, UnstructuredParcelable},
23+
impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable,
2624
unstable_api::{status_result, AsNative},
2725
StatusCode,
2826
};
@@ -210,81 +208,40 @@ impl Clone for HardwareBuffer {
210208
}
211209
}
212210

213-
impl Serialize for HardwareBuffer {
214-
fn serialize(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
215-
SerializeOption::serialize_option(Some(self), parcel)
211+
impl UnstructuredParcelable for HardwareBuffer {
212+
fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
213+
let status =
214+
// SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
215+
// because it must have been allocated by `AHardwareBuffer_allocate`,
216+
// `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
217+
// released it.
218+
unsafe { AHardwareBuffer_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) };
219+
status_result(status)
216220
}
217-
}
218221

219-
impl SerializeOption for HardwareBuffer {
220-
fn serialize_option(
221-
this: Option<&Self>,
222-
parcel: &mut BorrowedParcel,
223-
) -> Result<(), StatusCode> {
224-
if let Some(this) = this {
225-
parcel.write(&NON_NULL_PARCELABLE_FLAG)?;
226-
227-
let status =
228-
// SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
229-
// because it must have been allocated by `AHardwareBuffer_allocate`,
230-
// `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
231-
// released it.
232-
unsafe { AHardwareBuffer_writeToParcel(this.0.as_ptr(), parcel.as_native_mut()) };
233-
status_result(status)
234-
} else {
235-
parcel.write(&NULL_PARCELABLE_FLAG)
236-
}
237-
}
238-
}
222+
fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
223+
let mut buffer = null_mut();
239224

240-
impl Deserialize for HardwareBuffer {
241-
type UninitType = Option<Self>;
225+
let status =
226+
// SAFETY: Both pointers must be valid because they are obtained from references.
227+
// `AHardwareBuffer_readFromParcel` doesn't store them or do anything else special
228+
// with them. If it returns success then it will have allocated a new
229+
// `AHardwareBuffer` and incremented the reference count, so we can use it until we
230+
// release it.
231+
unsafe { AHardwareBuffer_readFromParcel(parcel.as_native(), &mut buffer) };
242232

243-
fn uninit() -> Option<Self> {
244-
None
245-
}
246-
247-
fn from_init(value: Self) -> Option<Self> {
248-
Some(value)
249-
}
250-
251-
fn deserialize(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
252-
DeserializeOption::deserialize_option(parcel)
253-
.transpose()
254-
.unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
255-
}
256-
}
233+
status_result(status)?;
257234

258-
impl DeserializeOption for HardwareBuffer {
259-
fn deserialize_option(parcel: &BorrowedParcel) -> Result<Option<Self>, StatusCode> {
260-
let present: i32 = parcel.read()?;
261-
match present {
262-
NULL_PARCELABLE_FLAG => Ok(None),
263-
NON_NULL_PARCELABLE_FLAG => {
264-
let mut buffer = null_mut();
265-
266-
let status =
267-
// SAFETY: Both pointers must be valid because they are obtained from references.
268-
// `AHardwareBuffer_readFromParcel` doesn't store them or do anything else special
269-
// with them. If it returns success then it will have allocated a new
270-
// `AHardwareBuffer` and incremented the reference count, so we can use it until we
271-
// release it.
272-
unsafe { AHardwareBuffer_readFromParcel(parcel.as_native(), &mut buffer) };
273-
274-
status_result(status)?;
275-
276-
Ok(Some(Self(NonNull::new(buffer).expect(
277-
"AHardwareBuffer_readFromParcel returned success but didn't allocate buffer",
278-
))))
279-
}
280-
_ => Err(StatusCode::BAD_VALUE),
281-
}
235+
Ok(Self(
236+
NonNull::new(buffer).expect(
237+
"AHardwareBuffer_readFromParcel returned success but didn't allocate buffer",
238+
),
239+
))
282240
}
283241
}
284242

285-
impl SerializeArray for HardwareBuffer {}
286-
287-
impl DeserializeArray for HardwareBuffer {}
243+
impl_deserialize_for_unstructured_parcelable!(HardwareBuffer);
244+
impl_serialize_for_unstructured_parcelable!(HardwareBuffer);
288245

289246
// SAFETY: The underlying *AHardwareBuffers can be moved between threads.
290247
unsafe impl Send for HardwareBuffer {}

0 commit comments

Comments
 (0)