rust: split Parcel enum into two types
Test: m
Bug: 200676345
Change-Id: I351ea0500035dafe0c8444cbb96074725c1c8630
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 4e048d7..bd2e695 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -17,7 +17,7 @@
//! Trait definitions for binder objects
use crate::error::{status_t, Result, StatusCode};
-use crate::parcel::{OwnedParcel, Parcel};
+use crate::parcel::{Parcel, BorrowedParcel};
use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
use crate::sys;
@@ -129,7 +129,7 @@
/// Handle and reply to a request to invoke a transaction on this object.
///
/// `reply` may be [`None`] if the sender does not expect a reply.
- fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
+ fn on_transact(&self, code: TransactionCode, data: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>) -> Result<()>;
/// Handle a request to invoke the dump transaction on this
/// object.
@@ -177,25 +177,25 @@
fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
/// Create a Parcel that can be used with `submit_transact`.
- fn prepare_transact(&self) -> Result<OwnedParcel>;
+ fn prepare_transact(&self) -> Result<Parcel>;
/// Perform a generic operation with the object.
///
- /// The provided [`OwnedParcel`] must have been created by a call to
+ /// The provided [`Parcel`] must have been created by a call to
/// `prepare_transact` on the same binder.
///
/// # Arguments
///
/// * `code` - Transaction code for the operation.
- /// * `data` - [`OwnedParcel`] with input data.
+ /// * `data` - [`Parcel`] with input data.
/// * `flags` - Transaction flags, e.g. marking the transaction as
/// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
fn submit_transact(
&self,
code: TransactionCode,
- data: OwnedParcel,
+ data: Parcel,
flags: TransactionFlags,
- ) -> Result<OwnedParcel>;
+ ) -> Result<Parcel>;
/// Perform a generic operation with the object. This is a convenience
/// method that internally calls `prepare_transact` followed by
@@ -206,15 +206,15 @@
/// * `flags` - Transaction flags, e.g. marking the transaction as
/// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
/// * `input_callback` A callback for building the `Parcel`.
- fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
+ fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
&self,
code: TransactionCode,
flags: TransactionFlags,
input_callback: F,
) -> Result<Parcel> {
let mut parcel = self.prepare_transact()?;
- input_callback(&mut parcel.borrowed())?;
- self.submit_transact(code, parcel, flags).map(OwnedParcel::into_parcel)
+ input_callback(parcel.borrowed())?;
+ self.submit_transact(code, parcel, flags)
}
}
@@ -475,8 +475,8 @@
/// fn on_transact(
/// &self,
/// code: TransactionCode,
-/// data: &Parcel,
-/// reply: &mut Parcel,
+/// data: &BorrowedParcel,
+/// reply: &mut BorrowedParcel,
/// ) -> Result<()> {
/// // ...
/// }
@@ -655,13 +655,13 @@
/// have the following type:
///
/// ```
-/// # use binder::{Interface, TransactionCode, Parcel};
+/// # use binder::{Interface, TransactionCode, BorrowedParcel};
/// # trait Placeholder {
/// fn on_transact(
/// service: &dyn Interface,
/// code: TransactionCode,
-/// data: &Parcel,
-/// reply: &mut Parcel,
+/// data: &BorrowedParcel,
+/// reply: &mut BorrowedParcel,
/// ) -> binder::Result<()>;
/// # }
/// ```
@@ -676,7 +676,7 @@
/// using the provided function, `on_transact`.
///
/// ```
-/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
+/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
///
/// pub trait IServiceManager: Interface {
/// // remote methods...
@@ -692,8 +692,8 @@
/// fn on_transact(
/// service: &dyn IServiceManager,
/// code: TransactionCode,
-/// data: &Parcel,
-/// reply: &mut Parcel,
+/// data: &BorrowedParcel,
+/// reply: &mut BorrowedParcel,
/// ) -> binder::Result<()> {
/// // ...
/// Ok(())
@@ -847,7 +847,7 @@
$descriptor
}
- fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
+ fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::BorrowedParcel<'_>, reply: &mut $crate::BorrowedParcel<'_>) -> $crate::Result<()> {
match $on_transact(&*self.0, code, data, reply) {
// The C++ backend converts UNEXPECTED_NULL into an exception
Err($crate::StatusCode::UNEXPECTED_NULL) => {
@@ -922,14 +922,14 @@
where
dyn $interface: $crate::Interface
{
- fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+ fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
let binder = $crate::Interface::as_binder(self);
parcel.write(&binder)
}
}
impl $crate::parcel::SerializeOption for dyn $interface + '_ {
- fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
parcel.write(&this.map($crate::Interface::as_binder))
}
}
@@ -988,14 +988,14 @@
}
impl<P: $crate::BinderAsyncPool> $crate::parcel::Serialize for dyn $async_interface<P> + '_ {
- fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+ fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
let binder = $crate::Interface::as_binder(self);
parcel.write(&binder)
}
}
impl<P: $crate::BinderAsyncPool> $crate::parcel::SerializeOption for dyn $async_interface<P> + '_ {
- fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
parcel.write(&this.map($crate::Interface::as_binder))
}
}
@@ -1040,26 +1040,26 @@
}
impl $crate::parcel::Serialize for $enum {
- fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+ fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
parcel.write(&self.0)
}
}
impl $crate::parcel::SerializeArray for $enum {
- fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+ fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
<$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
}
}
impl $crate::parcel::Deserialize for $enum {
- fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
+ fn deserialize(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Self> {
parcel.read().map(Self)
}
}
impl $crate::parcel::DeserializeArray for $enum {
- fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
+ fn deserialize_array(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Option<Vec<Self>>> {
let v: Option<Vec<$backing>> =
<$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
Ok(v.map(|v| v.into_iter().map(Self).collect()))
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index 2ac2d2f..cce55c0 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -50,8 +50,8 @@
//! fn on_transact(
//! service: &dyn ITest,
//! code: TransactionCode,
-//! _data: &Parcel,
-//! reply: &mut Parcel,
+//! _data: &BorrowedParcel,
+//! reply: &mut BorrowedParcel,
//! ) -> binder::Result<()> {
//! match code {
//! SpIBinder::FIRST_CALL_TRANSACTION => {
@@ -115,7 +115,7 @@
pub use crate::binder_async::{BoxFuture, BinderAsyncPool};
pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
pub use native::{add_service, force_lazy_services_persist, register_lazy_service, Binder};
-pub use parcel::{OwnedParcel, Parcel};
+pub use parcel::{BorrowedParcel, Parcel};
pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service};
pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder};
pub use state::{ProcessState, ThreadState};
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
index a91092e..f5d7187 100644
--- a/libs/binder/rust/src/native.rs
+++ b/libs/binder/rust/src/native.rs
@@ -18,7 +18,7 @@
AsNative, Interface, InterfaceClassMethods, Remotable, Stability, TransactionCode,
};
use crate::error::{status_result, status_t, Result, StatusCode};
-use crate::parcel::{Parcel, Serialize};
+use crate::parcel::{BorrowedParcel, Serialize};
use crate::proxy::SpIBinder;
use crate::sys;
@@ -161,8 +161,8 @@
/// # fn on_transact(
/// # service: &dyn IBar,
/// # code: TransactionCode,
- /// # data: &Parcel,
- /// # reply: &mut Parcel,
+ /// # data: &BorrowedParcel,
+ /// # reply: &mut BorrowedParcel,
/// # ) -> binder::Result<()> {
/// # Ok(())
/// # }
@@ -277,8 +277,8 @@
reply: *mut sys::AParcel,
) -> status_t {
let res = {
- let mut reply = Parcel::borrowed(reply).unwrap();
- let data = Parcel::borrowed(data as *mut sys::AParcel).unwrap();
+ let mut reply = BorrowedParcel::from_raw(reply).unwrap();
+ let data = BorrowedParcel::from_raw(data as *mut sys::AParcel).unwrap();
let object = sys::AIBinder_getUserData(binder);
let binder: &T = &*(object as *const T);
binder.on_transact(code, &data, &mut reply)
@@ -384,7 +384,7 @@
}
impl<B: Remotable> Serialize for Binder<B> {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
parcel.write_binder(Some(&self.as_binder()))
}
}
@@ -503,8 +503,8 @@
fn on_transact(
&self,
_code: TransactionCode,
- _data: &Parcel,
- _reply: &mut Parcel,
+ _data: &BorrowedParcel<'_>,
+ _reply: &mut BorrowedParcel<'_>,
) -> Result<()> {
Ok(())
}
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index a0e1478..206b90c 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -21,11 +21,10 @@
use crate::proxy::SpIBinder;
use crate::sys;
-use std::cell::RefCell;
use std::convert::TryInto;
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
-use std::ptr;
+use std::ptr::{self, NonNull};
use std::fmt;
mod file_descriptor;
@@ -46,53 +45,41 @@
/// other side of the IPC, and references to live Binder objects that will
/// result in the other side receiving a proxy Binder connected with the
/// original Binder in the Parcel.
-pub enum Parcel {
- /// Owned parcel pointer
- Owned(*mut sys::AParcel),
- /// Borrowed parcel pointer (will not be destroyed on drop)
- Borrowed(*mut sys::AParcel),
-}
-
-/// A variant of Parcel that is known to be owned.
-pub struct OwnedParcel {
- ptr: *mut sys::AParcel,
+///
+/// This type represents a parcel that is owned by Rust code.
+#[repr(transparent)]
+pub struct Parcel {
+ ptr: NonNull<sys::AParcel>,
}
/// # Safety
///
/// This type guarantees that it owns the AParcel and that all access to
-/// the AParcel happens through the OwnedParcel, so it is ok to send across
+/// the AParcel happens through the Parcel, so it is ok to send across
/// threads.
-unsafe impl Send for OwnedParcel {}
+unsafe impl Send for Parcel {}
-/// A variant of Parcel that is known to be borrowed.
+/// Container for a message (data and object references) that can be sent
+/// through Binder.
+///
+/// This object is a borrowed variant of [`Parcel`]. It is a separate type from
+/// `&mut Parcel` because it is not valid to `mem::swap` two parcels.
+#[repr(transparent)]
pub struct BorrowedParcel<'a> {
- inner: Parcel,
+ ptr: NonNull<sys::AParcel>,
_lifetime: PhantomData<&'a mut Parcel>,
}
-impl OwnedParcel {
- /// Create a new empty `OwnedParcel`.
- pub fn new() -> OwnedParcel {
+impl Parcel {
+ /// Create a new empty `Parcel`.
+ pub fn new() -> Parcel {
let ptr = unsafe {
// Safety: If `AParcel_create` succeeds, it always returns
// a valid pointer. If it fails, the process will crash.
sys::AParcel_create()
};
- assert!(!ptr.is_null());
- Self { ptr }
- }
-
- /// Convert the provided parcel to an owned parcel, or return `None` if it
- /// is borrowed.
- pub fn try_from(parcel: Parcel) -> Option<OwnedParcel> {
- match &parcel {
- Parcel::Owned(ptr) => {
- let ptr = *ptr;
- std::mem::forget(parcel);
- Some(OwnedParcel { ptr })
- }
- Parcel::Borrowed(_) => None,
+ Self {
+ ptr: NonNull::new(ptr).expect("AParcel_create returned null pointer")
}
}
@@ -107,108 +94,43 @@
///
/// Additionally, the caller must guarantee that it is valid to take
/// ownership of the AParcel object. All future access to the AParcel
- /// must happen through this `OwnedParcel`.
+ /// must happen through this `Parcel`.
///
- /// Because `OwnedParcel` implements `Send`, the pointer must never point
- /// to any thread-local data, e.g., a variable on the stack, either directly
- /// or indirectly.
- pub unsafe fn from_raw(ptr: *mut sys::AParcel) -> Option<OwnedParcel> {
- ptr.as_mut().map(|ptr| Self { ptr })
+ /// Because `Parcel` implements `Send`, the pointer must never point to any
+ /// thread-local data, e.g., a variable on the stack, either directly or
+ /// indirectly.
+ pub unsafe fn from_raw(ptr: *mut sys::AParcel) -> Option<Parcel> {
+ NonNull::new(ptr).map(|ptr| Self { ptr })
}
/// Consume the parcel, transferring ownership to the caller.
pub(crate) fn into_raw(self) -> *mut sys::AParcel {
- let ptr = self.ptr;
+ let ptr = self.ptr.as_ptr();
let _ = ManuallyDrop::new(self);
ptr
}
- /// Convert this `OwnedParcel` into an owned `Parcel`.
- pub fn into_parcel(self) -> Parcel {
- Parcel::Owned(self.into_raw())
- }
-
/// Get a borrowed view into the contents of this `Parcel`.
pub fn borrowed(&mut self) -> BorrowedParcel<'_> {
+ // Safety: The raw pointer is a valid pointer to an AParcel, and the
+ // lifetime of the returned `BorrowedParcel` is tied to `self`, so the
+ // borrow checker will ensure that the `AParcel` can only be accessed
+ // via the `BorrowParcel` until it goes out of scope.
BorrowedParcel {
- inner: Parcel::Borrowed(self.ptr),
+ ptr: self.ptr,
_lifetime: PhantomData,
}
}
-}
-impl Default for OwnedParcel {
- fn default() -> Self {
- Self::new()
- }
-}
-
-impl Clone for OwnedParcel {
- fn clone(&self) -> Self {
- let mut new_parcel = Self::new();
- new_parcel
- .borrowed()
- .append_all_from(&Parcel::Borrowed(self.ptr))
- .expect("Failed to append from Parcel");
- new_parcel
- }
-}
-
-impl<'a> std::ops::Deref for BorrowedParcel<'a> {
- type Target = Parcel;
- fn deref(&self) -> &Parcel {
- &self.inner
- }
-}
-impl<'a> std::ops::DerefMut for BorrowedParcel<'a> {
- fn deref_mut(&mut self) -> &mut Parcel {
- &mut self.inner
- }
-}
-
-/// # Safety
-///
-/// The `Parcel` constructors guarantee that a `Parcel` object will always
-/// contain a valid pointer to an `AParcel`.
-unsafe impl AsNative<sys::AParcel> for Parcel {
- fn as_native(&self) -> *const sys::AParcel {
- match *self {
- Self::Owned(x) | Self::Borrowed(x) => x,
+ /// Get an immutable borrowed view into the contents of this `Parcel`.
+ pub fn borrowed_ref(&self) -> &BorrowedParcel<'_> {
+ // Safety: Parcel and BorrowedParcel are both represented in the same
+ // way as a NonNull<sys::AParcel> due to their use of repr(transparent),
+ // so casting references as done here is valid.
+ unsafe {
+ &*(self as *const Parcel as *const BorrowedParcel<'_>)
}
}
-
- fn as_native_mut(&mut self) -> *mut sys::AParcel {
- match *self {
- Self::Owned(x) | Self::Borrowed(x) => x,
- }
- }
-}
-
-impl Parcel {
- /// Create a new empty `Parcel`.
- ///
- /// Creates a new owned empty parcel that can be written to
- /// using the serialization methods and appended to and
- /// from using `append_from` and `append_from_all`.
- pub fn new() -> Parcel {
- let parcel = unsafe {
- // Safety: If `AParcel_create` succeeds, it always returns
- // a valid pointer. If it fails, the process will crash.
- sys::AParcel_create()
- };
- assert!(!parcel.is_null());
- Self::Owned(parcel)
- }
-
- /// Create a borrowed reference to a parcel object from a raw pointer.
- ///
- /// # Safety
- ///
- /// This constructor is safe if the raw pointer parameter is either null
- /// (resulting in `None`), or a valid pointer to an `AParcel` object.
- pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> {
- ptr.as_mut().map(|ptr| Self::Borrowed(ptr))
- }
}
impl Default for Parcel {
@@ -221,14 +143,77 @@
fn clone(&self) -> Self {
let mut new_parcel = Self::new();
new_parcel
- .append_all_from(self)
+ .borrowed()
+ .append_all_from(self.borrowed_ref())
.expect("Failed to append from Parcel");
new_parcel
}
}
+impl<'a> BorrowedParcel<'a> {
+ /// Create a borrowed reference to a parcel object from a raw pointer.
+ ///
+ /// # Safety
+ ///
+ /// This constructor is safe if the raw pointer parameter is either null
+ /// (resulting in `None`), or a valid pointer to an `AParcel` object.
+ ///
+ /// Since the raw pointer is not restricted by any lifetime, the lifetime on
+ /// the returned `BorrowedParcel` object can be chosen arbitrarily by the
+ /// caller. The caller must ensure it is valid to mutably borrow the AParcel
+ /// for the duration of the lifetime that the caller chooses. Note that
+ /// since this is a mutable borrow, it must have exclusive access to the
+ /// AParcel for the duration of the borrow.
+ pub unsafe fn from_raw(ptr: *mut sys::AParcel) -> Option<BorrowedParcel<'a>> {
+ Some(Self {
+ ptr: NonNull::new(ptr)?,
+ _lifetime: PhantomData,
+ })
+ }
+
+ /// Get a sub-reference to this reference to the parcel.
+ pub fn reborrow(&mut self) -> BorrowedParcel<'_> {
+ // Safety: The raw pointer is a valid pointer to an AParcel, and the
+ // lifetime of the returned `BorrowedParcel` is tied to `self`, so the
+ // borrow checker will ensure that the `AParcel` can only be accessed
+ // via the `BorrowParcel` until it goes out of scope.
+ BorrowedParcel {
+ ptr: self.ptr,
+ _lifetime: PhantomData,
+ }
+ }
+}
+
+/// # Safety
+///
+/// The `Parcel` constructors guarantee that a `Parcel` object will always
+/// contain a valid pointer to an `AParcel`.
+unsafe impl AsNative<sys::AParcel> for Parcel {
+ fn as_native(&self) -> *const sys::AParcel {
+ self.ptr.as_ptr()
+ }
+
+ fn as_native_mut(&mut self) -> *mut sys::AParcel {
+ self.ptr.as_ptr()
+ }
+}
+
+/// # Safety
+///
+/// The `BorrowedParcel` constructors guarantee that a `BorrowedParcel` object
+/// will always contain a valid pointer to an `AParcel`.
+unsafe impl<'a> AsNative<sys::AParcel> for BorrowedParcel<'a> {
+ fn as_native(&self) -> *const sys::AParcel {
+ self.ptr.as_ptr()
+ }
+
+ fn as_native_mut(&mut self) -> *mut sys::AParcel {
+ self.ptr.as_ptr()
+ }
+}
+
// Data serialization methods
-impl Parcel {
+impl<'a> BorrowedParcel<'a> {
/// Data written to parcelable is zero'd before being deleted or reallocated.
pub fn mark_sensitive(&mut self) {
unsafe {
@@ -237,12 +222,12 @@
}
}
- /// Write a type that implements [`Serialize`] to the `Parcel`.
+ /// Write a type that implements [`Serialize`] to the parcel.
pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
parcelable.serialize(self)
}
- /// Writes the length of a slice to the `Parcel`.
+ /// Writes the length of a slice to the parcel.
///
/// This is used in AIDL-generated client side code to indicate the
/// allocated space for an output array parameter.
@@ -255,7 +240,7 @@
}
}
- /// Perform a series of writes to the `Parcel`, prepended with the length
+ /// Perform a series of writes to the parcel, prepended with the length
/// (in bytes) of the written data.
///
/// The length `0i32` will be written to the parcel first, followed by the
@@ -269,7 +254,7 @@
///
/// ```
/// # use binder::{Binder, Interface, Parcel};
- /// # let mut parcel = Parcel::Owned(std::ptr::null_mut());
+ /// # let mut parcel = Parcel::new();
/// parcel.sized_write(|subparcel| {
/// subparcel.write(&1u32)?;
/// subparcel.write(&2u32)?;
@@ -283,14 +268,14 @@
/// [16i32, 1u32, 2u32, 3u32]
/// ```
pub fn sized_write<F>(&mut self, f: F) -> Result<()>
- where for<'a>
- F: Fn(&'a WritableSubParcel<'a>) -> Result<()>
+ where
+ for<'b> F: FnOnce(&'b mut WritableSubParcel<'b>) -> Result<()>
{
let start = self.get_data_position();
self.write(&0i32)?;
{
- let subparcel = WritableSubParcel(RefCell::new(self));
- f(&subparcel)?;
+ let mut subparcel = WritableSubParcel(self.reborrow());
+ f(&mut subparcel)?;
}
let end = self.get_data_position();
unsafe {
@@ -307,8 +292,8 @@
/// Returns the current position in the parcel data.
pub fn get_data_position(&self) -> i32 {
unsafe {
- // Safety: `Parcel` always contains a valid pointer to an `AParcel`,
- // and this call is otherwise safe.
+ // Safety: `BorrowedParcel` always contains a valid pointer to an
+ // `AParcel`, and this call is otherwise safe.
sys::AParcel_getDataPosition(self.as_native())
}
}
@@ -316,8 +301,8 @@
/// Returns the total size of the parcel.
pub fn get_data_size(&self) -> i32 {
unsafe {
- // Safety: `Parcel` always contains a valid pointer to an `AParcel`,
- // and this call is otherwise safe.
+ // Safety: `BorrowedParcel` always contains a valid pointer to an
+ // `AParcel`, and this call is otherwise safe.
sys::AParcel_getDataSize(self.as_native())
}
}
@@ -335,11 +320,11 @@
status_result(sys::AParcel_setDataPosition(self.as_native(), pos))
}
- /// Append a subset of another `Parcel`.
+ /// Append a subset of another parcel.
///
/// This appends `size` bytes of data from `other` starting at offset
- /// `start` to the current `Parcel`, or returns an error if not possible.
- pub fn append_from(&mut self, other: &Self, start: i32, size: i32) -> Result<()> {
+ /// `start` to the current parcel, or returns an error if not possible.
+ pub fn append_from(&mut self, other: &impl AsNative<sys::AParcel>, start: i32, size: i32) -> Result<()> {
let status = unsafe {
// Safety: `Parcel::appendFrom` from C++ checks that `start`
// and `size` are in bounds, and returns an error otherwise.
@@ -354,33 +339,125 @@
status_result(status)
}
- /// Append the contents of another `Parcel`.
- pub fn append_all_from(&mut self, other: &Self) -> Result<()> {
- self.append_from(other, 0, other.get_data_size())
+ /// Append the contents of another parcel.
+ pub fn append_all_from(&mut self, other: &impl AsNative<sys::AParcel>) -> Result<()> {
+ // Safety: `BorrowedParcel` always contains a valid pointer to an
+ // `AParcel`, and this call is otherwise safe.
+ let size = unsafe { sys::AParcel_getDataSize(other.as_native()) };
+ self.append_from(other, 0, size)
}
}
-/// A segment of a writable parcel, used for [`Parcel::sized_write`].
-pub struct WritableSubParcel<'a>(RefCell<&'a mut Parcel>);
+/// A segment of a writable parcel, used for [`BorrowedParcel::sized_write`].
+pub struct WritableSubParcel<'a>(BorrowedParcel<'a>);
impl<'a> WritableSubParcel<'a> {
/// Write a type that implements [`Serialize`] to the sub-parcel.
- pub fn write<S: Serialize + ?Sized>(&self, parcelable: &S) -> Result<()> {
- parcelable.serialize(&mut *self.0.borrow_mut())
+ pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
+ parcelable.serialize(&mut self.0)
+ }
+}
+
+impl Parcel {
+ /// Data written to parcelable is zero'd before being deleted or reallocated.
+ pub fn mark_sensitive(&mut self) {
+ self.borrowed().mark_sensitive()
+ }
+
+ /// Write a type that implements [`Serialize`] to the parcel.
+ pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
+ self.borrowed().write(parcelable)
+ }
+
+ /// Writes the length of a slice to the parcel.
+ ///
+ /// This is used in AIDL-generated client side code to indicate the
+ /// allocated space for an output array parameter.
+ pub fn write_slice_size<T>(&mut self, slice: Option<&[T]>) -> Result<()> {
+ self.borrowed().write_slice_size(slice)
+ }
+
+ /// Perform a series of writes to the parcel, prepended with the length
+ /// (in bytes) of the written data.
+ ///
+ /// The length `0i32` will be written to the parcel first, followed by the
+ /// writes performed by the callback. The initial length will then be
+ /// updated to the length of all data written by the callback, plus the
+ /// size of the length elemement itself (4 bytes).
+ ///
+ /// # Examples
+ ///
+ /// After the following call:
+ ///
+ /// ```
+ /// # use binder::{Binder, Interface, Parcel};
+ /// # let mut parcel = Parcel::new();
+ /// parcel.sized_write(|subparcel| {
+ /// subparcel.write(&1u32)?;
+ /// subparcel.write(&2u32)?;
+ /// subparcel.write(&3u32)
+ /// });
+ /// ```
+ ///
+ /// `parcel` will contain the following:
+ ///
+ /// ```ignore
+ /// [16i32, 1u32, 2u32, 3u32]
+ /// ```
+ pub fn sized_write<F>(&mut self, f: F) -> Result<()>
+ where
+ for<'b> F: FnOnce(&'b mut WritableSubParcel<'b>) -> Result<()>
+ {
+ self.borrowed().sized_write(f)
+ }
+
+ /// Returns the current position in the parcel data.
+ pub fn get_data_position(&self) -> i32 {
+ self.borrowed_ref().get_data_position()
+ }
+
+ /// Returns the total size of the parcel.
+ pub fn get_data_size(&self) -> i32 {
+ self.borrowed_ref().get_data_size()
+ }
+
+ /// Move the current read/write position in the parcel.
+ ///
+ /// # Safety
+ ///
+ /// This method is safe if `pos` is less than the current size of the parcel
+ /// data buffer. Otherwise, we are relying on correct bounds checking in the
+ /// Parcel C++ code on every subsequent read or write to this parcel. If all
+ /// accesses are bounds checked, this call is still safe, but we can't rely
+ /// on that.
+ pub unsafe fn set_data_position(&self, pos: i32) -> Result<()> {
+ self.borrowed_ref().set_data_position(pos)
+ }
+
+ /// Append a subset of another parcel.
+ ///
+ /// This appends `size` bytes of data from `other` starting at offset
+ /// `start` to the current parcel, or returns an error if not possible.
+ pub fn append_from(&mut self, other: &impl AsNative<sys::AParcel>, start: i32, size: i32) -> Result<()> {
+ self.borrowed().append_from(other, start, size)
+ }
+
+ /// Append the contents of another parcel.
+ pub fn append_all_from(&mut self, other: &impl AsNative<sys::AParcel>) -> Result<()> {
+ self.borrowed().append_all_from(other)
}
}
// Data deserialization methods
-impl Parcel {
- /// Attempt to read a type that implements [`Deserialize`] from this
- /// `Parcel`.
+impl<'a> BorrowedParcel<'a> {
+ /// Attempt to read a type that implements [`Deserialize`] from this parcel.
pub fn read<D: Deserialize>(&self) -> Result<D> {
D::deserialize(self)
}
- /// Attempt to read a type that implements [`Deserialize`] from this
- /// `Parcel` onto an existing value. This operation will overwrite the old
- /// value partially or completely, depending on how much data is available.
+ /// Attempt to read a type that implements [`Deserialize`] from this parcel
+ /// onto an existing value. This operation will overwrite the old value
+ /// partially or completely, depending on how much data is available.
pub fn read_onto<D: Deserialize>(&self, x: &mut D) -> Result<()> {
x.deserialize_from(self)
}
@@ -413,9 +490,9 @@
/// });
/// ```
///
- pub fn sized_read<F>(&self, mut f: F) -> Result<()>
+ pub fn sized_read<F>(&self, f: F) -> Result<()>
where
- for<'a> F: FnMut(ReadableSubParcel<'a>) -> Result<()>
+ for<'b> F: FnOnce(ReadableSubParcel<'b>) -> Result<()>
{
let start = self.get_data_position();
let parcelable_size: i32 = self.read()?;
@@ -430,7 +507,10 @@
}
let subparcel = ReadableSubParcel {
- parcel: self,
+ parcel: BorrowedParcel {
+ ptr: self.ptr,
+ _lifetime: PhantomData,
+ },
end_position: end,
};
f(subparcel)?;
@@ -444,8 +524,8 @@
Ok(())
}
- /// Read a vector size from the `Parcel` and resize the given output vector
- /// to be correctly sized for that amount of data.
+ /// Read a vector size from the parcel and resize the given output vector to
+ /// be correctly sized for that amount of data.
///
/// This method is used in AIDL-generated server side code for methods that
/// take a mutable slice reference parameter.
@@ -463,7 +543,7 @@
Ok(())
}
- /// Read a vector size from the `Parcel` and either create a correctly sized
+ /// Read a vector size from the parcel and either create a correctly sized
/// vector for that amount of data or set the output parameter to None if
/// the vector should be null.
///
@@ -491,7 +571,7 @@
/// A segment of a readable parcel, used for [`Parcel::sized_read`].
pub struct ReadableSubParcel<'a> {
- parcel: &'a Parcel,
+ parcel: BorrowedParcel<'a>,
end_position: i32,
}
@@ -501,7 +581,7 @@
// The caller should have checked this,
// but it can't hurt to double-check
assert!(self.has_more_data());
- D::deserialize(self.parcel)
+ D::deserialize(&self.parcel)
}
/// Check if the sub-parcel has more data to read
@@ -510,11 +590,82 @@
}
}
-// Internal APIs
impl Parcel {
+ /// Attempt to read a type that implements [`Deserialize`] from this parcel.
+ pub fn read<D: Deserialize>(&self) -> Result<D> {
+ self.borrowed_ref().read()
+ }
+
+ /// Attempt to read a type that implements [`Deserialize`] from this parcel
+ /// onto an existing value. This operation will overwrite the old value
+ /// partially or completely, depending on how much data is available.
+ pub fn read_onto<D: Deserialize>(&self, x: &mut D) -> Result<()> {
+ self.borrowed_ref().read_onto(x)
+ }
+
+ /// Safely read a sized parcelable.
+ ///
+ /// Read the size of a parcelable, compute the end position
+ /// of that parcelable, then build a sized readable sub-parcel
+ /// and call a closure with the sub-parcel as its parameter.
+ /// The closure can keep reading data from the sub-parcel
+ /// until it runs out of input data. The closure is responsible
+ /// for calling [`ReadableSubParcel::has_more_data`] to check for
+ /// more data before every read, at least until Rust generators
+ /// are stabilized.
+ /// After the closure returns, skip to the end of the current
+ /// parcelable regardless of how much the closure has read.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// let mut parcelable = Default::default();
+ /// parcel.sized_read(|subparcel| {
+ /// if subparcel.has_more_data() {
+ /// parcelable.a = subparcel.read()?;
+ /// }
+ /// if subparcel.has_more_data() {
+ /// parcelable.b = subparcel.read()?;
+ /// }
+ /// Ok(())
+ /// });
+ /// ```
+ ///
+ pub fn sized_read<F>(&self, f: F) -> Result<()>
+ where
+ for<'b> F: FnOnce(ReadableSubParcel<'b>) -> Result<()>
+ {
+ self.borrowed_ref().sized_read(f)
+ }
+
+ /// Read a vector size from the parcel and resize the given output vector to
+ /// be correctly sized for that amount of data.
+ ///
+ /// This method is used in AIDL-generated server side code for methods that
+ /// take a mutable slice reference parameter.
+ pub fn resize_out_vec<D: Default + Deserialize>(&self, out_vec: &mut Vec<D>) -> Result<()> {
+ self.borrowed_ref().resize_out_vec(out_vec)
+ }
+
+ /// Read a vector size from the parcel and either create a correctly sized
+ /// vector for that amount of data or set the output parameter to None if
+ /// the vector should be null.
+ ///
+ /// This method is used in AIDL-generated server side code for methods that
+ /// take a mutable slice reference parameter.
+ pub fn resize_nullable_out_vec<D: Default + Deserialize>(
+ &self,
+ out_vec: &mut Option<Vec<D>>,
+ ) -> Result<()> {
+ self.borrowed_ref().resize_nullable_out_vec(out_vec)
+ }
+}
+
+// Internal APIs
+impl<'a> BorrowedParcel<'a> {
pub(crate) fn write_binder(&mut self, binder: Option<&SpIBinder>) -> Result<()> {
unsafe {
- // Safety: `Parcel` always contains a valid pointer to an
+ // Safety: `BorrowedParcel` always contains a valid pointer to an
// `AParcel`. `AsNative` for `Option<SpIBinder`> will either return
// null or a valid pointer to an `AIBinder`, both of which are
// valid, safe inputs to `AParcel_writeStrongBinder`.
@@ -534,7 +685,7 @@
pub(crate) fn read_binder(&self) -> Result<Option<SpIBinder>> {
let mut binder = ptr::null_mut();
let status = unsafe {
- // Safety: `Parcel` always contains a valid pointer to an
+ // Safety: `BorrowedParcel` always contains a valid pointer to an
// `AParcel`. We pass a valid, mutable out pointer to the `binder`
// parameter. After this call, `binder` will be either null or a
// valid pointer to an `AIBinder` owned by the caller.
@@ -554,25 +705,11 @@
impl Drop for Parcel {
fn drop(&mut self) {
// Run the C++ Parcel complete object destructor
- if let Self::Owned(ptr) = *self {
- unsafe {
- // Safety: `Parcel` always contains a valid pointer to an
- // `AParcel`. If we own the parcel, we can safely delete it
- // here.
- sys::AParcel_delete(ptr)
- }
- }
- }
-}
-
-impl Drop for OwnedParcel {
- fn drop(&mut self) {
- // Run the C++ Parcel complete object destructor
unsafe {
- // Safety: `OwnedParcel` always contains a valid pointer to an
+ // Safety: `Parcel` always contains a valid pointer to an
// `AParcel`. Since we own the parcel, we can safely delete it
// here.
- sys::AParcel_delete(self.ptr)
+ sys::AParcel_delete(self.ptr.as_ptr())
}
}
}
@@ -584,9 +721,9 @@
}
}
-impl fmt::Debug for OwnedParcel {
+impl<'a> fmt::Debug for BorrowedParcel<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("OwnedParcel")
+ f.debug_struct("BorrowedParcel")
.finish()
}
}
@@ -608,7 +745,7 @@
assert_eq!(parcel.read::<Option<String>>(), Ok(None));
assert_eq!(parcel.read::<String>(), Err(StatusCode::UNEXPECTED_NULL));
- assert_eq!(parcel.read_binder().err(), Some(StatusCode::BAD_TYPE));
+ assert_eq!(parcel.borrowed_ref().read_binder().err(), Some(StatusCode::BAD_TYPE));
parcel.write(&1i32).unwrap();
diff --git a/libs/binder/rust/src/parcel/file_descriptor.rs b/libs/binder/rust/src/parcel/file_descriptor.rs
index 8bcc5d0..b0dea94 100644
--- a/libs/binder/rust/src/parcel/file_descriptor.rs
+++ b/libs/binder/rust/src/parcel/file_descriptor.rs
@@ -15,7 +15,7 @@
*/
use super::{
- Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray,
+ Deserialize, DeserializeArray, DeserializeOption, BorrowedParcel, Serialize, SerializeArray,
SerializeOption,
};
use crate::binder::AsNative;
@@ -61,7 +61,7 @@
}
impl Serialize for ParcelFileDescriptor {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
let fd = self.0.as_raw_fd();
let status = unsafe {
// Safety: `Parcel` always contains a valid pointer to an
@@ -78,7 +78,7 @@
impl SerializeArray for ParcelFileDescriptor {}
impl SerializeOption for ParcelFileDescriptor {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
if let Some(f) = this {
f.serialize(parcel)
} else {
@@ -95,7 +95,7 @@
}
impl DeserializeOption for ParcelFileDescriptor {
- fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+ fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
let mut fd = -1i32;
unsafe {
// Safety: `Parcel` always contains a valid pointer to an
@@ -125,7 +125,7 @@
}
impl Deserialize for ParcelFileDescriptor {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
Deserialize::deserialize(parcel)
.transpose()
.unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index db9d8b0..9007cba 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -16,14 +16,14 @@
use crate::binder::{AsNative, FromIBinder, Stability, Strong};
use crate::error::{status_result, status_t, Result, Status, StatusCode};
-use crate::parcel::Parcel;
+use crate::parcel::BorrowedParcel;
use crate::proxy::SpIBinder;
use crate::sys;
use std::convert::{TryFrom, TryInto};
use std::ffi::c_void;
use std::os::raw::{c_char, c_ulong};
-use std::mem::{self, MaybeUninit};
+use std::mem::{self, MaybeUninit, ManuallyDrop};
use std::ptr;
use std::slice;
@@ -39,7 +39,7 @@
/// `Serialize::serialize` and its variants are generally
/// preferred over this function, since the former also
/// prepend a header.
- fn write_to_parcel(&self, parcel: &mut Parcel) -> Result<()>;
+ fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>;
/// Internal deserialization function for parcelables.
///
@@ -47,26 +47,26 @@
/// `Deserialize::deserialize` and its variants are generally
/// preferred over this function, since the former also
/// parse the additional header.
- fn read_from_parcel(&mut self, parcel: &Parcel) -> Result<()>;
+ fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()>;
}
/// A struct whose instances can be written to a [`Parcel`].
// Might be able to hook this up as a serde backend in the future?
pub trait Serialize {
/// Serialize this instance into the given [`Parcel`].
- fn serialize(&self, parcel: &mut Parcel) -> Result<()>;
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>;
}
/// A struct whose instances can be restored from a [`Parcel`].
// Might be able to hook this up as a serde backend in the future?
pub trait Deserialize: Sized {
/// Deserialize an instance from the given [`Parcel`].
- fn deserialize(parcel: &Parcel) -> Result<Self>;
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self>;
/// Deserialize an instance from the given [`Parcel`] onto the
/// current object. This operation will overwrite the old value
/// partially or completely, depending on how much data is available.
- fn deserialize_from(&mut self, parcel: &Parcel) -> Result<()> {
+ fn deserialize_from(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> {
*self = Self::deserialize(parcel)?;
Ok(())
}
@@ -80,8 +80,8 @@
// We want the default implementation for most types, but an override for
// a few special ones like `readByteArray` for `u8`.
pub trait SerializeArray: Serialize + Sized {
- /// Serialize an array of this type into the given [`Parcel`].
- fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+ /// Serialize an array of this type into the given parcel.
+ fn serialize_array(slice: &[Self], parcel: &mut BorrowedParcel<'_>) -> Result<()> {
let res = unsafe {
// Safety: Safe FFI, slice will always be a safe pointer to pass.
sys::AParcel_writeParcelableArray(
@@ -111,7 +111,7 @@
let slice: &[T] = slice::from_raw_parts(array.cast(), index+1);
- let mut parcel = match Parcel::borrowed(parcel) {
+ let mut parcel = match BorrowedParcel::from_raw(parcel) {
None => return StatusCode::UNEXPECTED_NULL as status_t,
Some(p) => p,
};
@@ -126,8 +126,8 @@
/// Defaults to calling Deserialize::deserialize() manually for every element,
/// but can be overridden for custom implementations like `readByteArray`.
pub trait DeserializeArray: Deserialize {
- /// Deserialize an array of type from the given [`Parcel`].
- fn deserialize_array(parcel: &Parcel) -> Result<Option<Vec<Self>>> {
+ /// Deserialize an array of type from the given parcel.
+ fn deserialize_array(parcel: &BorrowedParcel<'_>) -> Result<Option<Vec<Self>>> {
let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
let res = unsafe {
// Safety: Safe FFI, vec is the correct opaque type expected by
@@ -173,7 +173,7 @@
None => return StatusCode::BAD_INDEX as status_t,
};
- let parcel = match Parcel::borrowed(parcel as *mut _) {
+ let parcel = match BorrowedParcel::from_raw(parcel as *mut _) {
None => return StatusCode::UNEXPECTED_NULL as status_t,
Some(p) => p,
};
@@ -205,8 +205,8 @@
// We also use it to provide a default implementation for AIDL-generated
// parcelables.
pub trait SerializeOption: Serialize {
- /// Serialize an Option of this type into the given [`Parcel`].
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ /// Serialize an Option of this type into the given parcel.
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
if let Some(inner) = this {
parcel.write(&NON_NULL_PARCELABLE_FLAG)?;
parcel.write(inner)
@@ -218,8 +218,8 @@
/// Helper trait for types that can be nullable when deserialized.
pub trait DeserializeOption: Deserialize {
- /// Deserialize an Option of this type from the given [`Parcel`].
- fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+ /// Deserialize an Option of this type from the given parcel.
+ fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
let null: i32 = parcel.read()?;
if null == NULL_PARCELABLE_FLAG {
Ok(None)
@@ -228,10 +228,10 @@
}
}
- /// Deserialize an Option of this type from the given [`Parcel`] onto the
+ /// Deserialize an Option of this type from the given parcel onto the
/// current object. This operation will overwrite the current value
/// partially or completely, depending on how much data is available.
- fn deserialize_option_from(this: &mut Option<Self>, parcel: &Parcel) -> Result<()> {
+ fn deserialize_option_from(this: &mut Option<Self>, parcel: &BorrowedParcel<'_>) -> Result<()> {
*this = Self::deserialize_option(parcel)?;
Ok(())
}
@@ -297,10 +297,23 @@
};
}
+/// Safety: All elements in the vector must be properly initialized.
+unsafe fn vec_assume_init<T>(vec: Vec<MaybeUninit<T>>) -> Vec<T> {
+ // We can convert from Vec<MaybeUninit<T>> to Vec<T> because MaybeUninit<T>
+ // has the same alignment and size as T, so the pointer to the vector
+ // allocation will be compatible.
+ let mut vec = ManuallyDrop::new(vec);
+ Vec::from_raw_parts(
+ vec.as_mut_ptr().cast(),
+ vec.len(),
+ vec.capacity(),
+ )
+}
+
macro_rules! impl_parcelable {
{Serialize, $ty:ty, $write_fn:path} => {
impl Serialize for $ty {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
unsafe {
// Safety: `Parcel` always contains a valid pointer to an
// `AParcel`, and any `$ty` literal value is safe to pass to
@@ -313,7 +326,7 @@
{Deserialize, $ty:ty, $read_fn:path} => {
impl Deserialize for $ty {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let mut val = Self::default();
unsafe {
// Safety: `Parcel` always contains a valid pointer to an
@@ -329,7 +342,7 @@
{SerializeArray, $ty:ty, $write_array_fn:path} => {
impl SerializeArray for $ty {
- fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+ fn serialize_array(slice: &[Self], parcel: &mut BorrowedParcel<'_>) -> Result<()> {
let status = unsafe {
// Safety: `Parcel` always contains a valid pointer to an
// `AParcel`. If the slice is > 0 length, `slice.as_ptr()`
@@ -353,7 +366,7 @@
{DeserializeArray, $ty:ty, $read_array_fn:path} => {
impl DeserializeArray for $ty {
- fn deserialize_array(parcel: &Parcel) -> Result<Option<Vec<Self>>> {
+ fn deserialize_array(parcel: &BorrowedParcel<'_>) -> Result<Option<Vec<Self>>> {
let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
let status = unsafe {
// Safety: `Parcel` always contains a valid pointer to an
@@ -371,11 +384,8 @@
// Safety: We are assuming that the NDK correctly
// initialized every element of the vector by now, so we
// know that all the MaybeUninits are now properly
- // initialized. We can transmute from Vec<MaybeUninit<T>> to
- // Vec<T> because MaybeUninit<T> has the same alignment and
- // size as T, so the pointer to the vector allocation will
- // be compatible.
- mem::transmute(vec)
+ // initialized.
+ vec.map(|vec| vec_assume_init(vec))
};
Ok(vec)
}
@@ -443,19 +453,19 @@
impl DeserializeArray for bool {}
impl Serialize for u8 {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
(*self as i8).serialize(parcel)
}
}
impl Deserialize for u8 {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
i8::deserialize(parcel).map(|v| v as u8)
}
}
impl SerializeArray for u8 {
- fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+ fn serialize_array(slice: &[Self], parcel: &mut BorrowedParcel<'_>) -> Result<()> {
let status = unsafe {
// Safety: `Parcel` always contains a valid pointer to an
// `AParcel`. If the slice is > 0 length, `slice.as_ptr()` will be a
@@ -474,19 +484,19 @@
}
impl Serialize for i16 {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
(*self as u16).serialize(parcel)
}
}
impl Deserialize for i16 {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
u16::deserialize(parcel).map(|v| v as i16)
}
}
impl SerializeArray for i16 {
- fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+ fn serialize_array(slice: &[Self], parcel: &mut BorrowedParcel<'_>) -> Result<()> {
let status = unsafe {
// Safety: `Parcel` always contains a valid pointer to an
// `AParcel`. If the slice is > 0 length, `slice.as_ptr()` will be a
@@ -505,7 +515,7 @@
}
impl SerializeOption for str {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
match this {
None => unsafe {
// Safety: `Parcel` always contains a valid pointer to an
@@ -541,7 +551,7 @@
}
impl Serialize for str {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Some(self).serialize(parcel)
}
}
@@ -549,7 +559,7 @@
impl SerializeArray for &str {}
impl Serialize for String {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Some(self.as_str()).serialize(parcel)
}
}
@@ -557,13 +567,13 @@
impl SerializeArray for String {}
impl SerializeOption for String {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
SerializeOption::serialize_option(this.map(String::as_str), parcel)
}
}
impl Deserialize for Option<String> {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let mut vec: Option<Vec<u8>> = None;
let status = unsafe {
// Safety: `Parcel` always contains a valid pointer to an `AParcel`.
@@ -591,7 +601,7 @@
impl DeserializeArray for Option<String> {}
impl Deserialize for String {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
Deserialize::deserialize(parcel)
.transpose()
.unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
@@ -601,19 +611,19 @@
impl DeserializeArray for String {}
impl<T: SerializeArray> Serialize for [T] {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
SerializeArray::serialize_array(self, parcel)
}
}
impl<T: SerializeArray> Serialize for Vec<T> {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
SerializeArray::serialize_array(&self[..], parcel)
}
}
impl<T: SerializeArray> SerializeOption for [T] {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
if let Some(v) = this {
SerializeArray::serialize_array(v, parcel)
} else {
@@ -623,13 +633,13 @@
}
impl<T: SerializeArray> SerializeOption for Vec<T> {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
SerializeOption::serialize_option(this.map(Vec::as_slice), parcel)
}
}
impl<T: DeserializeArray> Deserialize for Vec<T> {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
DeserializeArray::deserialize_array(parcel)
.transpose()
.unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
@@ -637,25 +647,25 @@
}
impl<T: DeserializeArray> DeserializeOption for Vec<T> {
- fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+ fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
DeserializeArray::deserialize_array(parcel)
}
}
impl Serialize for Stability {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
i32::from(*self).serialize(parcel)
}
}
impl Deserialize for Stability {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
i32::deserialize(parcel).and_then(Stability::try_from)
}
}
impl Serialize for Status {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
unsafe {
// Safety: `Parcel` always contains a valid pointer to an `AParcel`
// and `Status` always contains a valid pointer to an `AStatus`, so
@@ -670,7 +680,7 @@
}
impl Deserialize for Status {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let mut status_ptr = ptr::null_mut();
let ret_status = unsafe {
// Safety: `Parcel` always contains a valid pointer to an
@@ -691,13 +701,13 @@
}
impl<T: Serialize + FromIBinder + ?Sized> Serialize for Strong<T> {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Serialize::serialize(&**self, parcel)
}
}
impl<T: SerializeOption + FromIBinder + ?Sized> SerializeOption for Strong<T> {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
SerializeOption::serialize_option(this.map(|b| &**b), parcel)
}
}
@@ -705,14 +715,14 @@
impl<T: Serialize + FromIBinder + ?Sized> SerializeArray for Strong<T> {}
impl<T: FromIBinder + ?Sized> Deserialize for Strong<T> {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
let ibinder: SpIBinder = parcel.read()?;
FromIBinder::try_from(ibinder)
}
}
impl<T: FromIBinder + ?Sized> DeserializeOption for Strong<T> {
- fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+ fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
let ibinder: Option<SpIBinder> = parcel.read()?;
ibinder.map(FromIBinder::try_from).transpose()
}
@@ -722,29 +732,29 @@
// We need these to support Option<&T> for all T
impl<T: Serialize + ?Sized> Serialize for &T {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Serialize::serialize(*self, parcel)
}
}
impl<T: SerializeOption + ?Sized> SerializeOption for &T {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
SerializeOption::serialize_option(this.copied(), parcel)
}
}
impl<T: SerializeOption> Serialize for Option<T> {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
SerializeOption::serialize_option(self.as_ref(), parcel)
}
}
impl<T: DeserializeOption> Deserialize for Option<T> {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
DeserializeOption::deserialize_option(parcel)
}
- fn deserialize_from(&mut self, parcel: &Parcel) -> Result<()> {
+ fn deserialize_from(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> {
DeserializeOption::deserialize_option_from(self, parcel)
}
}
@@ -762,7 +772,7 @@
impl $crate::parcel::Serialize for $parcelable {
fn serialize(
&self,
- parcel: &mut $crate::parcel::Parcel,
+ parcel: &mut $crate::parcel::BorrowedParcel<'_>,
) -> $crate::Result<()> {
<Self as $crate::parcel::SerializeOption>::serialize_option(
Some(self),
@@ -776,7 +786,7 @@
impl $crate::parcel::SerializeOption for $parcelable {
fn serialize_option(
this: Option<&Self>,
- parcel: &mut $crate::parcel::Parcel,
+ parcel: &mut $crate::parcel::BorrowedParcel<'_>,
) -> $crate::Result<()> {
if let Some(this) = this {
use $crate::parcel::Parcelable;
@@ -796,13 +806,12 @@
/// `Deserialize`, `DeserializeArray` and `DeserializeOption` for
/// structured parcelables. The target type must implement the
/// `Parcelable` trait.
-/// ```
#[macro_export]
macro_rules! impl_deserialize_for_parcelable {
($parcelable:ident) => {
impl $crate::parcel::Deserialize for $parcelable {
fn deserialize(
- parcel: &$crate::parcel::Parcel,
+ parcel: &$crate::parcel::BorrowedParcel<'_>,
) -> $crate::Result<Self> {
$crate::parcel::DeserializeOption::deserialize_option(parcel)
.transpose()
@@ -810,7 +819,7 @@
}
fn deserialize_from(
&mut self,
- parcel: &$crate::parcel::Parcel,
+ parcel: &$crate::parcel::BorrowedParcel<'_>,
) -> $crate::Result<()> {
let status: i32 = parcel.read()?;
if status == $crate::parcel::NULL_PARCELABLE_FLAG {
@@ -826,7 +835,7 @@
impl $crate::parcel::DeserializeOption for $parcelable {
fn deserialize_option(
- parcel: &$crate::parcel::Parcel,
+ parcel: &$crate::parcel::BorrowedParcel<'_>,
) -> $crate::Result<Option<Self>> {
let mut result = None;
Self::deserialize_option_from(&mut result, parcel)?;
@@ -834,7 +843,7 @@
}
fn deserialize_option_from(
this: &mut Option<Self>,
- parcel: &$crate::parcel::Parcel,
+ parcel: &$crate::parcel::BorrowedParcel<'_>,
) -> $crate::Result<()> {
let status: i32 = parcel.read()?;
if status == $crate::parcel::NULL_PARCELABLE_FLAG {
@@ -851,326 +860,332 @@
}
impl<T: Serialize> Serialize for Box<T> {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
Serialize::serialize(&**self, parcel)
}
}
impl<T: Deserialize> Deserialize for Box<T> {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
Deserialize::deserialize(parcel).map(Box::new)
}
}
impl<T: SerializeOption> SerializeOption for Box<T> {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
SerializeOption::serialize_option(this.map(|inner| &**inner), parcel)
}
}
impl<T: DeserializeOption> DeserializeOption for Box<T> {
- fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+ fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
DeserializeOption::deserialize_option(parcel).map(|t| t.map(Box::new))
}
}
-#[test]
-fn test_custom_parcelable() {
- struct Custom(u32, bool, String, Vec<String>);
+#[cfg(test)]
+mod tests {
+ use crate::Parcel;
+ use super::*;
- impl Serialize for Custom {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
- self.0.serialize(parcel)?;
- self.1.serialize(parcel)?;
- self.2.serialize(parcel)?;
- self.3.serialize(parcel)
+ #[test]
+ fn test_custom_parcelable() {
+ struct Custom(u32, bool, String, Vec<String>);
+
+ impl Serialize for Custom {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
+ self.0.serialize(parcel)?;
+ self.1.serialize(parcel)?;
+ self.2.serialize(parcel)?;
+ self.3.serialize(parcel)
+ }
}
- }
- impl Deserialize for Custom {
- fn deserialize(parcel: &Parcel) -> Result<Self> {
- Ok(Custom(
- parcel.read()?,
- parcel.read()?,
- parcel.read()?,
- parcel.read::<Option<Vec<String>>>()?.unwrap(),
- ))
+ impl Deserialize for Custom {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
+ Ok(Custom(
+ parcel.read()?,
+ parcel.read()?,
+ parcel.read()?,
+ parcel.read::<Option<Vec<String>>>()?.unwrap(),
+ ))
+ }
}
+
+ let string8 = "Custom Parcelable".to_string();
+
+ let s1 = "str1".to_string();
+ let s2 = "str2".to_string();
+ let s3 = "str3".to_string();
+
+ let strs = vec![s1, s2, s3];
+
+ let custom = Custom(123_456_789, true, string8, strs);
+
+ let mut parcel = Parcel::new();
+ let start = parcel.get_data_position();
+
+ assert!(custom.serialize(&mut parcel.borrowed()).is_ok());
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let custom2 = Custom::deserialize(parcel.borrowed_ref()).unwrap();
+
+ assert_eq!(custom2.0, 123_456_789);
+ assert!(custom2.1);
+ assert_eq!(custom2.2, custom.2);
+ assert_eq!(custom2.3, custom.3);
}
- let string8 = "Custom Parcelable".to_string();
+ #[test]
+ #[allow(clippy::excessive_precision)]
+ fn test_slice_parcelables() {
+ let bools = [true, false, false, true];
- let s1 = "str1".to_string();
- let s2 = "str2".to_string();
- let s3 = "str3".to_string();
+ let mut parcel = Parcel::new();
+ let start = parcel.get_data_position();
- let strs = vec![s1, s2, s3];
+ assert!(bools.serialize(&mut parcel.borrowed()).is_ok());
- let custom = Custom(123_456_789, true, string8, strs);
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
- let mut parcel = Parcel::new();
- let start = parcel.get_data_position();
+ assert_eq!(parcel.read::<u32>().unwrap(), 4);
+ assert_eq!(parcel.read::<u32>().unwrap(), 1);
+ assert_eq!(parcel.read::<u32>().unwrap(), 0);
+ assert_eq!(parcel.read::<u32>().unwrap(), 0);
+ assert_eq!(parcel.read::<u32>().unwrap(), 1);
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
- assert!(custom.serialize(&mut parcel).is_ok());
+ let vec = Vec::<bool>::deserialize(parcel.borrowed_ref()).unwrap();
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
+ assert_eq!(vec, [true, false, false, true]);
+
+ let u8s = [101u8, 255, 42, 117];
+
+ let mut parcel = Parcel::new();
+ let start = parcel.get_data_position();
+
+ assert!(parcel.write(&u8s[..]).is_ok());
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+ assert_eq!(parcel.read::<u32>().unwrap(), 0x752aff65); // bytes
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<u8>::deserialize(parcel.borrowed_ref()).unwrap();
+ assert_eq!(vec, [101, 255, 42, 117]);
+
+ let i8s = [-128i8, 127, 42, -117];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ assert!(parcel.write(&i8s[..]).is_ok());
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+ assert_eq!(parcel.read::<u32>().unwrap(), 0x8b2a7f80); // bytes
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<u8>::deserialize(parcel.borrowed_ref()).unwrap();
+ assert_eq!(vec, [-128i8 as u8, 127, 42, -117i8 as u8]);
+
+ let u16s = [u16::max_value(), 12_345, 42, 117];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(u16s.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+ assert_eq!(parcel.read::<u32>().unwrap(), 0xffff); // u16::max_value()
+ assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
+ assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+ assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<u16>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ assert_eq!(vec, [u16::max_value(), 12_345, 42, 117]);
+
+ let i16s = [i16::max_value(), i16::min_value(), 42, -117];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(i16s.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+ assert_eq!(parcel.read::<u32>().unwrap(), 0x7fff); // i16::max_value()
+ assert_eq!(parcel.read::<u32>().unwrap(), 0x8000); // i16::min_value()
+ assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+ assert_eq!(parcel.read::<u32>().unwrap(), 0xff8b); // -117
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<i16>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ assert_eq!(vec, [i16::max_value(), i16::min_value(), 42, -117]);
+
+ let u32s = [u32::max_value(), 12_345, 42, 117];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(u32s.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+ assert_eq!(parcel.read::<u32>().unwrap(), 0xffffffff); // u32::max_value()
+ assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
+ assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+ assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<u32>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ assert_eq!(vec, [u32::max_value(), 12_345, 42, 117]);
+
+ let i32s = [i32::max_value(), i32::min_value(), 42, -117];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(i32s.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+ assert_eq!(parcel.read::<u32>().unwrap(), 0x7fffffff); // i32::max_value()
+ assert_eq!(parcel.read::<u32>().unwrap(), 0x80000000); // i32::min_value()
+ assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+ assert_eq!(parcel.read::<u32>().unwrap(), 0xffffff8b); // -117
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<i32>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ assert_eq!(vec, [i32::max_value(), i32::min_value(), 42, -117]);
+
+ let u64s = [u64::max_value(), 12_345, 42, 117];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(u64s.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<u64>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ assert_eq!(vec, [u64::max_value(), 12_345, 42, 117]);
+
+ let i64s = [i64::max_value(), i64::min_value(), 42, -117];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(i64s.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<i64>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ assert_eq!(vec, [i64::max_value(), i64::min_value(), 42, -117]);
+
+ let f32s = [
+ std::f32::NAN,
+ std::f32::INFINITY,
+ 1.23456789,
+ std::f32::EPSILON,
+ ];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(f32s.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<f32>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ // NAN != NAN so we can't use it in the assert_eq:
+ assert!(vec[0].is_nan());
+ assert_eq!(vec[1..], f32s[1..]);
+
+ let f64s = [
+ std::f64::NAN,
+ std::f64::INFINITY,
+ 1.234567890123456789,
+ std::f64::EPSILON,
+ ];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(f64s.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<f64>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ // NAN != NAN so we can't use it in the assert_eq:
+ assert!(vec[0].is_nan());
+ assert_eq!(vec[1..], f64s[1..]);
+
+ let s1 = "Hello, Binder!";
+ let s2 = "This is a utf8 string.";
+ let s3 = "Some more text here.";
+ let s4 = "Embedded nulls \0 \0";
+
+ let strs = [s1, s2, s3, s4];
+
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+ assert!(strs.serialize(&mut parcel.borrowed()).is_ok());
+ unsafe {
+ assert!(parcel.set_data_position(start).is_ok());
+ }
+
+ let vec = Vec::<String>::deserialize(parcel.borrowed_ref()).unwrap();
+
+ assert_eq!(vec, strs);
}
-
- let custom2 = Custom::deserialize(&parcel).unwrap();
-
- assert_eq!(custom2.0, 123_456_789);
- assert!(custom2.1);
- assert_eq!(custom2.2, custom.2);
- assert_eq!(custom2.3, custom.3);
-}
-
-#[test]
-#[allow(clippy::excessive_precision)]
-fn test_slice_parcelables() {
- let bools = [true, false, false, true];
-
- let mut parcel = Parcel::new();
- let start = parcel.get_data_position();
-
- assert!(bools.serialize(&mut parcel).is_ok());
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- assert_eq!(parcel.read::<u32>().unwrap(), 4);
- assert_eq!(parcel.read::<u32>().unwrap(), 1);
- assert_eq!(parcel.read::<u32>().unwrap(), 0);
- assert_eq!(parcel.read::<u32>().unwrap(), 0);
- assert_eq!(parcel.read::<u32>().unwrap(), 1);
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<bool>::deserialize(&parcel).unwrap();
-
- assert_eq!(vec, [true, false, false, true]);
-
- let u8s = [101u8, 255, 42, 117];
-
- let mut parcel = Parcel::new();
- let start = parcel.get_data_position();
-
- assert!(parcel.write(&u8s[..]).is_ok());
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
- assert_eq!(parcel.read::<u32>().unwrap(), 0x752aff65); // bytes
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<u8>::deserialize(&parcel).unwrap();
- assert_eq!(vec, [101, 255, 42, 117]);
-
- let i8s = [-128i8, 127, 42, -117];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- assert!(parcel.write(&i8s[..]).is_ok());
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
- assert_eq!(parcel.read::<u32>().unwrap(), 0x8b2a7f80); // bytes
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<u8>::deserialize(&parcel).unwrap();
- assert_eq!(vec, [-128i8 as u8, 127, 42, -117i8 as u8]);
-
- let u16s = [u16::max_value(), 12_345, 42, 117];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(u16s.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
- assert_eq!(parcel.read::<u32>().unwrap(), 0xffff); // u16::max_value()
- assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
- assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
- assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<u16>::deserialize(&parcel).unwrap();
-
- assert_eq!(vec, [u16::max_value(), 12_345, 42, 117]);
-
- let i16s = [i16::max_value(), i16::min_value(), 42, -117];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(i16s.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
- assert_eq!(parcel.read::<u32>().unwrap(), 0x7fff); // i16::max_value()
- assert_eq!(parcel.read::<u32>().unwrap(), 0x8000); // i16::min_value()
- assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
- assert_eq!(parcel.read::<u32>().unwrap(), 0xff8b); // -117
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<i16>::deserialize(&parcel).unwrap();
-
- assert_eq!(vec, [i16::max_value(), i16::min_value(), 42, -117]);
-
- let u32s = [u32::max_value(), 12_345, 42, 117];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(u32s.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
- assert_eq!(parcel.read::<u32>().unwrap(), 0xffffffff); // u32::max_value()
- assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
- assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
- assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<u32>::deserialize(&parcel).unwrap();
-
- assert_eq!(vec, [u32::max_value(), 12_345, 42, 117]);
-
- let i32s = [i32::max_value(), i32::min_value(), 42, -117];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(i32s.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
- assert_eq!(parcel.read::<u32>().unwrap(), 0x7fffffff); // i32::max_value()
- assert_eq!(parcel.read::<u32>().unwrap(), 0x80000000); // i32::min_value()
- assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
- assert_eq!(parcel.read::<u32>().unwrap(), 0xffffff8b); // -117
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<i32>::deserialize(&parcel).unwrap();
-
- assert_eq!(vec, [i32::max_value(), i32::min_value(), 42, -117]);
-
- let u64s = [u64::max_value(), 12_345, 42, 117];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(u64s.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<u64>::deserialize(&parcel).unwrap();
-
- assert_eq!(vec, [u64::max_value(), 12_345, 42, 117]);
-
- let i64s = [i64::max_value(), i64::min_value(), 42, -117];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(i64s.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<i64>::deserialize(&parcel).unwrap();
-
- assert_eq!(vec, [i64::max_value(), i64::min_value(), 42, -117]);
-
- let f32s = [
- std::f32::NAN,
- std::f32::INFINITY,
- 1.23456789,
- std::f32::EPSILON,
- ];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(f32s.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<f32>::deserialize(&parcel).unwrap();
-
- // NAN != NAN so we can't use it in the assert_eq:
- assert!(vec[0].is_nan());
- assert_eq!(vec[1..], f32s[1..]);
-
- let f64s = [
- std::f64::NAN,
- std::f64::INFINITY,
- 1.234567890123456789,
- std::f64::EPSILON,
- ];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(f64s.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<f64>::deserialize(&parcel).unwrap();
-
- // NAN != NAN so we can't use it in the assert_eq:
- assert!(vec[0].is_nan());
- assert_eq!(vec[1..], f64s[1..]);
-
- let s1 = "Hello, Binder!";
- let s2 = "This is a utf8 string.";
- let s3 = "Some more text here.";
- let s4 = "Embedded nulls \0 \0";
-
- let strs = [s1, s2, s3, s4];
-
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
- assert!(strs.serialize(&mut parcel).is_ok());
- unsafe {
- assert!(parcel.set_data_position(start).is_ok());
- }
-
- let vec = Vec::<String>::deserialize(&parcel).unwrap();
-
- assert_eq!(vec, strs);
}
diff --git a/libs/binder/rust/src/parcel/parcelable_holder.rs b/libs/binder/rust/src/parcel/parcelable_holder.rs
index bccfd2d..b4282b2 100644
--- a/libs/binder/rust/src/parcel/parcelable_holder.rs
+++ b/libs/binder/rust/src/parcel/parcelable_holder.rs
@@ -16,7 +16,7 @@
use crate::binder::Stability;
use crate::error::{Result, StatusCode};
-use crate::parcel::{OwnedParcel, Parcel, Parcelable};
+use crate::parcel::{Parcel, BorrowedParcel, Parcelable};
use crate::{impl_deserialize_for_parcelable, impl_serialize_for_parcelable};
use downcast_rs::{impl_downcast, DowncastSync};
@@ -50,7 +50,7 @@
parcelable: Arc<dyn AnyParcelable>,
name: String,
},
- Parcel(OwnedParcel),
+ Parcel(Parcel),
}
impl Default for ParcelableHolderData {
@@ -148,7 +148,6 @@
}
}
ParcelableHolderData::Parcel(ref mut parcel) => {
- let parcel = parcel.borrowed();
unsafe {
// Safety: 0 should always be a valid position.
parcel.set_data_position(0)?;
@@ -160,7 +159,7 @@
}
let mut parcelable = T::default();
- parcelable.read_from_parcel(&parcel)?;
+ parcelable.read_from_parcel(parcel.borrowed_ref())?;
let parcelable = Arc::new(parcelable);
let result = Arc::clone(&parcelable);
@@ -181,7 +180,7 @@
impl_deserialize_for_parcelable!(ParcelableHolder);
impl Parcelable for ParcelableHolder {
- fn write_to_parcel(&self, parcel: &mut Parcel) -> Result<()> {
+ fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
parcel.write(&self.stability)?;
let mut data = self.data.lock().unwrap();
@@ -214,14 +213,13 @@
Ok(())
}
ParcelableHolderData::Parcel(ref mut p) => {
- let p = p.borrowed();
parcel.write(&p.get_data_size())?;
- parcel.append_all_from(&p)
+ parcel.append_all_from(&*p)
}
}
}
- fn read_from_parcel(&mut self, parcel: &Parcel) -> Result<()> {
+ fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> {
self.stability = parcel.read()?;
let data_size: i32 = parcel.read()?;
@@ -242,10 +240,8 @@
.checked_add(data_size)
.ok_or(StatusCode::BAD_VALUE)?;
- let mut new_parcel = OwnedParcel::new();
- new_parcel
- .borrowed()
- .append_from(parcel, data_start, data_size)?;
+ let mut new_parcel = Parcel::new();
+ new_parcel.append_from(parcel, data_start, data_size)?;
*self.data.get_mut().unwrap() = ParcelableHolderData::Parcel(new_parcel);
unsafe {
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index a8d0c33..83553d7 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -22,8 +22,7 @@
};
use crate::error::{status_result, Result, StatusCode};
use crate::parcel::{
- Deserialize, DeserializeArray, DeserializeOption, OwnedParcel, Parcel, Serialize, SerializeArray,
- SerializeOption,
+ Parcel, BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Serialize, SerializeArray, SerializeOption,
};
use crate::sys;
@@ -235,7 +234,7 @@
}
impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
- fn prepare_transact(&self) -> Result<OwnedParcel> {
+ fn prepare_transact(&self) -> Result<Parcel> {
let mut input = ptr::null_mut();
let status = unsafe {
// Safety: `SpIBinder` guarantees that `self` always contains a
@@ -255,16 +254,16 @@
// Safety: At this point, `input` is either a valid, owned `AParcel`
// pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
// taking ownership of the parcel.
- OwnedParcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL)
+ Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL)
}
}
fn submit_transact(
&self,
code: TransactionCode,
- data: OwnedParcel,
+ data: Parcel,
flags: TransactionFlags,
- ) -> Result<OwnedParcel> {
+ ) -> Result<Parcel> {
let mut reply = ptr::null_mut();
let status = unsafe {
// Safety: `SpIBinder` guarantees that `self` always contains a
@@ -299,7 +298,7 @@
// construct a `Parcel` out of it. `AIBinder_transact` passes
// ownership of the `reply` parcel to Rust, so we need to
// construct an owned variant.
- OwnedParcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL)
+ Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL)
}
}
@@ -415,13 +414,13 @@
}
impl Serialize for SpIBinder {
- fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+ fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
parcel.write_binder(Some(self))
}
}
impl SerializeOption for SpIBinder {
- fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+ fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
parcel.write_binder(this)
}
}
@@ -429,7 +428,7 @@
impl SerializeArray for SpIBinder {}
impl Deserialize for SpIBinder {
- fn deserialize(parcel: &Parcel) -> Result<SpIBinder> {
+ fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
parcel
.read_binder()
.transpose()
@@ -438,7 +437,7 @@
}
impl DeserializeOption for SpIBinder {
- fn deserialize_option(parcel: &Parcel) -> Result<Option<SpIBinder>> {
+ fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
parcel.read_binder()
}
}