Loading libs/binder/rust/src/binder.rs +8 −8 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,7 @@ //! Trait definitions for binder objects //! Trait definitions for binder objects use crate::error::{status_t, Result, StatusCode}; use crate::error::{status_t, Result, StatusCode}; use crate::parcel::Parcel; use crate::parcel::{OwnedParcel, Parcel}; use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder}; use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder}; use crate::sys; use crate::sys; Loading Loading @@ -177,25 +177,25 @@ pub trait IBinderInternal: IBinder { fn get_extension(&mut self) -> Result<Option<SpIBinder>>; fn get_extension(&mut self) -> Result<Option<SpIBinder>>; /// Create a Parcel that can be used with `submit_transact`. /// Create a Parcel that can be used with `submit_transact`. fn prepare_transact(&self) -> Result<Parcel>; fn prepare_transact(&self) -> Result<OwnedParcel>; /// Perform a generic operation with the object. /// Perform a generic operation with the object. /// /// /// The provided [`Parcel`] must have been created by a call to /// The provided [`OwnedParcel`] must have been created by a call to /// `prepare_transact` on the same binder. /// `prepare_transact` on the same binder. /// /// /// # Arguments /// # Arguments /// /// /// * `code` - Transaction code for the operation. /// * `code` - Transaction code for the operation. /// * `data` - [`Parcel`] with input data. /// * `data` - [`OwnedParcel`] with input data. /// * `flags` - Transaction flags, e.g. marking the transaction as /// * `flags` - Transaction flags, e.g. marking the transaction as /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)). /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)). fn submit_transact( fn submit_transact( &self, &self, code: TransactionCode, code: TransactionCode, data: Parcel, data: OwnedParcel, flags: TransactionFlags, flags: TransactionFlags, ) -> Result<Parcel>; ) -> Result<OwnedParcel>; /// Perform a generic operation with the object. This is a convenience /// Perform a generic operation with the object. This is a convenience /// method that internally calls `prepare_transact` followed by /// method that internally calls `prepare_transact` followed by Loading @@ -213,8 +213,8 @@ pub trait IBinderInternal: IBinder { input_callback: F, input_callback: F, ) -> Result<Parcel> { ) -> Result<Parcel> { let mut parcel = self.prepare_transact()?; let mut parcel = self.prepare_transact()?; input_callback(&mut parcel)?; input_callback(&mut parcel.borrowed())?; self.submit_transact(code, parcel, flags) self.submit_transact(code, parcel, flags).map(OwnedParcel::into_parcel) } } } } Loading libs/binder/rust/src/lib.rs +1 −1 Original line number Original line Diff line number Diff line Loading @@ -113,7 +113,7 @@ pub use crate::binder::{ }; }; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; pub use native::{add_service, force_lazy_services_persist, register_lazy_service, Binder}; pub use native::{add_service, force_lazy_services_persist, register_lazy_service, Binder}; pub use parcel::Parcel; pub use parcel::{OwnedParcel, Parcel}; pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service}; pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service}; pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder}; pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder}; pub use state::{ProcessState, ThreadState}; pub use state::{ProcessState, ThreadState}; Loading libs/binder/rust/src/parcel.rs +120 −27 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ use crate::sys; use std::cell::RefCell; use std::cell::RefCell; use std::convert::TryInto; use std::convert::TryInto; use std::marker::PhantomData; use std::mem::ManuallyDrop; use std::mem::ManuallyDrop; use std::ptr; use std::ptr; use std::fmt; use std::fmt; Loading Loading @@ -52,6 +53,106 @@ pub enum Parcel { Borrowed(*mut sys::AParcel), Borrowed(*mut sys::AParcel), } } /// A variant of Parcel that is known to be owned. pub struct OwnedParcel { ptr: *mut 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 /// threads. unsafe impl Send for OwnedParcel {} /// A variant of Parcel that is known to be borrowed. pub struct BorrowedParcel<'a> { inner: Parcel, _lifetime: PhantomData<&'a mut Parcel>, } impl OwnedParcel { /// Create a new empty `OwnedParcel`. pub fn new() -> OwnedParcel { 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 } } /// Create an owned 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. The /// parcel object must be owned by the caller prior to this call, as this /// constructor takes ownership of the parcel and will destroy it on drop. /// /// 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`. /// /// 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 }) } /// Consume the parcel, transferring ownership to the caller. pub(crate) fn into_raw(self) -> *mut sys::AParcel { let ptr = self.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<'_> { BorrowedParcel { inner: Parcel::Borrowed(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 /// # Safety /// /// /// The `Parcel` constructors guarantee that a `Parcel` object will always /// The `Parcel` constructors guarantee that a `Parcel` object will always Loading Loading @@ -95,33 +196,6 @@ impl Parcel { pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> { pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> { ptr.as_mut().map(|ptr| Self::Borrowed(ptr)) ptr.as_mut().map(|ptr| Self::Borrowed(ptr)) } } /// Create an owned 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. The /// parcel object must be owned by the caller prior to this call, as this /// constructor takes ownership of the parcel and will destroy it on drop. pub(crate) unsafe fn owned(ptr: *mut sys::AParcel) -> Option<Parcel> { ptr.as_mut().map(|ptr| Self::Owned(ptr)) } /// Consume the parcel, transferring ownership to the caller if the parcel /// was owned. pub(crate) fn into_raw(mut self) -> *mut sys::AParcel { let ptr = self.as_native_mut(); let _ = ManuallyDrop::new(self); ptr } pub(crate) fn is_owned(&self) -> bool { match *self { Self::Owned(_) => true, Self::Borrowed(_) => false, } } } } impl Default for Parcel { impl Default for Parcel { Loading Loading @@ -478,6 +552,18 @@ impl Drop for Parcel { } } } } 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 // `AParcel`. Since we own the parcel, we can safely delete it // here. sys::AParcel_delete(self.ptr) } } } impl fmt::Debug for Parcel { impl fmt::Debug for Parcel { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Parcel") f.debug_struct("Parcel") Loading @@ -485,6 +571,13 @@ impl fmt::Debug for Parcel { } } } } impl fmt::Debug for OwnedParcel { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OwnedParcel") .finish() } } #[test] #[test] fn test_read_write() { fn test_read_write() { let mut parcel = Parcel::new(); let mut parcel = Parcel::new(); Loading libs/binder/rust/src/proxy.rs +8 −10 Original line number Original line Diff line number Diff line Loading @@ -22,7 +22,7 @@ use crate::binder::{ }; }; use crate::error::{status_result, Result, StatusCode}; use crate::error::{status_result, Result, StatusCode}; use crate::parcel::{ use crate::parcel::{ Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray, Deserialize, DeserializeArray, DeserializeOption, OwnedParcel, Parcel, Serialize, SerializeArray, SerializeOption, SerializeOption, }; }; use crate::sys; use crate::sys; Loading Loading @@ -235,7 +235,7 @@ impl Drop for SpIBinder { } } impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { fn prepare_transact(&self) -> Result<Parcel> { fn prepare_transact(&self) -> Result<OwnedParcel> { let mut input = ptr::null_mut(); let mut input = ptr::null_mut(); let status = unsafe { let status = unsafe { // Safety: `SpIBinder` guarantees that `self` always contains a // Safety: `SpIBinder` guarantees that `self` always contains a Loading @@ -253,20 +253,19 @@ impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { unsafe { unsafe { // Safety: At this point, `input` is either a valid, owned `AParcel` // Safety: At this point, `input` is either a valid, owned `AParcel` // pointer, or null. `Parcel::owned` safely handles both cases, // pointer, or null. `OwnedParcel::from_raw` safely handles both cases, // taking ownership of the parcel. // taking ownership of the parcel. Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL) OwnedParcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL) } } } } fn submit_transact( fn submit_transact( &self, &self, code: TransactionCode, code: TransactionCode, data: Parcel, data: OwnedParcel, flags: TransactionFlags, flags: TransactionFlags, ) -> Result<Parcel> { ) -> Result<OwnedParcel> { let mut reply = ptr::null_mut(); let mut reply = ptr::null_mut(); assert!(data.is_owned()); let status = unsafe { let status = unsafe { // Safety: `SpIBinder` guarantees that `self` always contains a // Safety: `SpIBinder` guarantees that `self` always contains a // valid pointer to an `AIBinder`. Although `IBinder::transact` is // valid pointer to an `AIBinder`. Although `IBinder::transact` is Loading Loading @@ -299,9 +298,8 @@ impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { // after the call to `AIBinder_transact` above, so we can // after the call to `AIBinder_transact` above, so we can // construct a `Parcel` out of it. `AIBinder_transact` passes // construct a `Parcel` out of it. `AIBinder_transact` passes // ownership of the `reply` parcel to Rust, so we need to // ownership of the `reply` parcel to Rust, so we need to // construct an owned variant. `Parcel::owned` takes ownership // construct an owned variant. // of the parcel pointer. OwnedParcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL) Parcel::owned(reply).ok_or(StatusCode::UNEXPECTED_NULL) } } } } Loading Loading
libs/binder/rust/src/binder.rs +8 −8 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,7 @@ //! Trait definitions for binder objects //! Trait definitions for binder objects use crate::error::{status_t, Result, StatusCode}; use crate::error::{status_t, Result, StatusCode}; use crate::parcel::Parcel; use crate::parcel::{OwnedParcel, Parcel}; use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder}; use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder}; use crate::sys; use crate::sys; Loading Loading @@ -177,25 +177,25 @@ pub trait IBinderInternal: IBinder { fn get_extension(&mut self) -> Result<Option<SpIBinder>>; fn get_extension(&mut self) -> Result<Option<SpIBinder>>; /// Create a Parcel that can be used with `submit_transact`. /// Create a Parcel that can be used with `submit_transact`. fn prepare_transact(&self) -> Result<Parcel>; fn prepare_transact(&self) -> Result<OwnedParcel>; /// Perform a generic operation with the object. /// Perform a generic operation with the object. /// /// /// The provided [`Parcel`] must have been created by a call to /// The provided [`OwnedParcel`] must have been created by a call to /// `prepare_transact` on the same binder. /// `prepare_transact` on the same binder. /// /// /// # Arguments /// # Arguments /// /// /// * `code` - Transaction code for the operation. /// * `code` - Transaction code for the operation. /// * `data` - [`Parcel`] with input data. /// * `data` - [`OwnedParcel`] with input data. /// * `flags` - Transaction flags, e.g. marking the transaction as /// * `flags` - Transaction flags, e.g. marking the transaction as /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)). /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)). fn submit_transact( fn submit_transact( &self, &self, code: TransactionCode, code: TransactionCode, data: Parcel, data: OwnedParcel, flags: TransactionFlags, flags: TransactionFlags, ) -> Result<Parcel>; ) -> Result<OwnedParcel>; /// Perform a generic operation with the object. This is a convenience /// Perform a generic operation with the object. This is a convenience /// method that internally calls `prepare_transact` followed by /// method that internally calls `prepare_transact` followed by Loading @@ -213,8 +213,8 @@ pub trait IBinderInternal: IBinder { input_callback: F, input_callback: F, ) -> Result<Parcel> { ) -> Result<Parcel> { let mut parcel = self.prepare_transact()?; let mut parcel = self.prepare_transact()?; input_callback(&mut parcel)?; input_callback(&mut parcel.borrowed())?; self.submit_transact(code, parcel, flags) self.submit_transact(code, parcel, flags).map(OwnedParcel::into_parcel) } } } } Loading
libs/binder/rust/src/lib.rs +1 −1 Original line number Original line Diff line number Diff line Loading @@ -113,7 +113,7 @@ pub use crate::binder::{ }; }; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; pub use native::{add_service, force_lazy_services_persist, register_lazy_service, Binder}; pub use native::{add_service, force_lazy_services_persist, register_lazy_service, Binder}; pub use parcel::Parcel; pub use parcel::{OwnedParcel, Parcel}; pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service}; pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service}; pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder}; pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder}; pub use state::{ProcessState, ThreadState}; pub use state::{ProcessState, ThreadState}; Loading
libs/binder/rust/src/parcel.rs +120 −27 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ use crate::sys; use std::cell::RefCell; use std::cell::RefCell; use std::convert::TryInto; use std::convert::TryInto; use std::marker::PhantomData; use std::mem::ManuallyDrop; use std::mem::ManuallyDrop; use std::ptr; use std::ptr; use std::fmt; use std::fmt; Loading Loading @@ -52,6 +53,106 @@ pub enum Parcel { Borrowed(*mut sys::AParcel), Borrowed(*mut sys::AParcel), } } /// A variant of Parcel that is known to be owned. pub struct OwnedParcel { ptr: *mut 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 /// threads. unsafe impl Send for OwnedParcel {} /// A variant of Parcel that is known to be borrowed. pub struct BorrowedParcel<'a> { inner: Parcel, _lifetime: PhantomData<&'a mut Parcel>, } impl OwnedParcel { /// Create a new empty `OwnedParcel`. pub fn new() -> OwnedParcel { 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 } } /// Create an owned 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. The /// parcel object must be owned by the caller prior to this call, as this /// constructor takes ownership of the parcel and will destroy it on drop. /// /// 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`. /// /// 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 }) } /// Consume the parcel, transferring ownership to the caller. pub(crate) fn into_raw(self) -> *mut sys::AParcel { let ptr = self.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<'_> { BorrowedParcel { inner: Parcel::Borrowed(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 /// # Safety /// /// /// The `Parcel` constructors guarantee that a `Parcel` object will always /// The `Parcel` constructors guarantee that a `Parcel` object will always Loading Loading @@ -95,33 +196,6 @@ impl Parcel { pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> { pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> { ptr.as_mut().map(|ptr| Self::Borrowed(ptr)) ptr.as_mut().map(|ptr| Self::Borrowed(ptr)) } } /// Create an owned 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. The /// parcel object must be owned by the caller prior to this call, as this /// constructor takes ownership of the parcel and will destroy it on drop. pub(crate) unsafe fn owned(ptr: *mut sys::AParcel) -> Option<Parcel> { ptr.as_mut().map(|ptr| Self::Owned(ptr)) } /// Consume the parcel, transferring ownership to the caller if the parcel /// was owned. pub(crate) fn into_raw(mut self) -> *mut sys::AParcel { let ptr = self.as_native_mut(); let _ = ManuallyDrop::new(self); ptr } pub(crate) fn is_owned(&self) -> bool { match *self { Self::Owned(_) => true, Self::Borrowed(_) => false, } } } } impl Default for Parcel { impl Default for Parcel { Loading Loading @@ -478,6 +552,18 @@ impl Drop for Parcel { } } } } 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 // `AParcel`. Since we own the parcel, we can safely delete it // here. sys::AParcel_delete(self.ptr) } } } impl fmt::Debug for Parcel { impl fmt::Debug for Parcel { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Parcel") f.debug_struct("Parcel") Loading @@ -485,6 +571,13 @@ impl fmt::Debug for Parcel { } } } } impl fmt::Debug for OwnedParcel { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OwnedParcel") .finish() } } #[test] #[test] fn test_read_write() { fn test_read_write() { let mut parcel = Parcel::new(); let mut parcel = Parcel::new(); Loading
libs/binder/rust/src/proxy.rs +8 −10 Original line number Original line Diff line number Diff line Loading @@ -22,7 +22,7 @@ use crate::binder::{ }; }; use crate::error::{status_result, Result, StatusCode}; use crate::error::{status_result, Result, StatusCode}; use crate::parcel::{ use crate::parcel::{ Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray, Deserialize, DeserializeArray, DeserializeOption, OwnedParcel, Parcel, Serialize, SerializeArray, SerializeOption, SerializeOption, }; }; use crate::sys; use crate::sys; Loading Loading @@ -235,7 +235,7 @@ impl Drop for SpIBinder { } } impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { fn prepare_transact(&self) -> Result<Parcel> { fn prepare_transact(&self) -> Result<OwnedParcel> { let mut input = ptr::null_mut(); let mut input = ptr::null_mut(); let status = unsafe { let status = unsafe { // Safety: `SpIBinder` guarantees that `self` always contains a // Safety: `SpIBinder` guarantees that `self` always contains a Loading @@ -253,20 +253,19 @@ impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { unsafe { unsafe { // Safety: At this point, `input` is either a valid, owned `AParcel` // Safety: At this point, `input` is either a valid, owned `AParcel` // pointer, or null. `Parcel::owned` safely handles both cases, // pointer, or null. `OwnedParcel::from_raw` safely handles both cases, // taking ownership of the parcel. // taking ownership of the parcel. Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL) OwnedParcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL) } } } } fn submit_transact( fn submit_transact( &self, &self, code: TransactionCode, code: TransactionCode, data: Parcel, data: OwnedParcel, flags: TransactionFlags, flags: TransactionFlags, ) -> Result<Parcel> { ) -> Result<OwnedParcel> { let mut reply = ptr::null_mut(); let mut reply = ptr::null_mut(); assert!(data.is_owned()); let status = unsafe { let status = unsafe { // Safety: `SpIBinder` guarantees that `self` always contains a // Safety: `SpIBinder` guarantees that `self` always contains a // valid pointer to an `AIBinder`. Although `IBinder::transact` is // valid pointer to an `AIBinder`. Although `IBinder::transact` is Loading Loading @@ -299,9 +298,8 @@ impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { // after the call to `AIBinder_transact` above, so we can // after the call to `AIBinder_transact` above, so we can // construct a `Parcel` out of it. `AIBinder_transact` passes // construct a `Parcel` out of it. `AIBinder_transact` passes // ownership of the `reply` parcel to Rust, so we need to // ownership of the `reply` parcel to Rust, so we need to // construct an owned variant. `Parcel::owned` takes ownership // construct an owned variant. // of the parcel pointer. OwnedParcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL) Parcel::owned(reply).ok_or(StatusCode::UNEXPECTED_NULL) } } } } Loading