Loading libs/binder/rust/binder_tokio/lib.rs +6 −6 Original line number Diff line number Diff line Loading @@ -28,8 +28,8 @@ //! //! [`Tokio`]: crate::Tokio use binder::public_api::{BinderAsyncPool, BoxFuture, Strong}; use binder::{FromIBinder, StatusCode, BinderAsyncRuntime}; use binder::{BinderAsyncPool, BoxFuture, FromIBinder, StatusCode, Strong}; use binder::binder_impl::BinderAsyncRuntime; use std::future::Future; /// Retrieve an existing service for a particular interface, sleeping for a few Loading @@ -37,12 +37,12 @@ use std::future::Future; pub async fn get_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Result<Strong<T>, StatusCode> { if binder::is_handling_transaction() { // See comment in the BinderAsyncPool impl. return binder::public_api::get_interface::<T>(name); return binder::get_interface::<T>(name); } let name = name.to_string(); let res = tokio::task::spawn_blocking(move || { binder::public_api::get_interface::<T>(&name) binder::get_interface::<T>(&name) }).await; // The `is_panic` branch is not actually reachable in Android as we compile Loading @@ -61,12 +61,12 @@ pub async fn get_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Res pub async fn wait_for_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Result<Strong<T>, StatusCode> { if binder::is_handling_transaction() { // See comment in the BinderAsyncPool impl. return binder::public_api::wait_for_interface::<T>(name); return binder::wait_for_interface::<T>(name); } let name = name.to_string(); let res = tokio::task::spawn_blocking(move || { binder::public_api::wait_for_interface::<T>(&name) binder::wait_for_interface::<T>(&name) }).await; // The `is_panic` branch is not actually reachable in Android as we compile Loading libs/binder/rust/src/binder.rs +53 −53 Original line number Diff line number Diff line Loading @@ -536,13 +536,13 @@ impl<I: FromIBinder + ?Sized> Eq for Weak<I> {} /// ``` macro_rules! binder_fn_get_class { ($class:ty) => { binder_fn_get_class!($crate::InterfaceClass::new::<$class>()); binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>()); }; ($constructor:expr) => { fn get_class() -> $crate::InterfaceClass { fn get_class() -> $crate::binder_impl::InterfaceClass { static CLASS_INIT: std::sync::Once = std::sync::Once::new(); static mut CLASS: Option<$crate::InterfaceClass> = None; static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None; CLASS_INIT.call_once(|| unsafe { // Safety: This assignment is guarded by the `CLASS_INIT` `Once` Loading Loading @@ -772,7 +772,7 @@ macro_rules! declare_binder_interface { native: $native($on_transact), proxy: $proxy {}, $(async: $async_interface,)? stability: $crate::Stability::default(), stability: $crate::binder_impl::Stability::default(), } } }; Loading Loading @@ -811,7 +811,7 @@ macro_rules! declare_binder_interface { $($fname: $fty = $finit),* }, $(async: $async_interface,)? stability: $crate::Stability::default(), stability: $crate::binder_impl::Stability::default(), } } }; Loading @@ -828,9 +828,9 @@ macro_rules! declare_binder_interface { } => { $crate::declare_binder_interface! { $interface[$descriptor] { @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")] @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")] native: $native($on_transact), @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")] @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")] proxy: $proxy { $($fname: $fty = $finit),* }, Loading Loading @@ -867,7 +867,7 @@ macro_rules! declare_binder_interface { } } impl $crate::Proxy for $proxy impl $crate::binder_impl::Proxy for $proxy where $proxy: $interface, { Loading @@ -875,7 +875,7 @@ macro_rules! declare_binder_interface { $descriptor } fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> { fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> { Ok(Self { binder, $($fname: $finit),* }) } } Loading @@ -887,19 +887,19 @@ macro_rules! declare_binder_interface { impl $native { /// Create a new binder service. pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> { let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability); let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability); #[cfg(not(android_vndk))] $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); $crate::Strong::new(Box::new(binder)) } } impl $crate::Remotable for $native { impl $crate::binder_impl::Remotable for $native { fn get_descriptor() -> &'static str { $descriptor } fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::BorrowedParcel<'_>, reply: &mut $crate::BorrowedParcel<'_>) -> $crate::Result<()> { fn on_transact(&self, code: $crate::binder_impl::TransactionCode, data: &$crate::binder_impl::BorrowedParcel<'_>, reply: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { match $on_transact(&*self.0, code, data, reply) { // The C++ backend converts UNEXPECTED_NULL into an exception Err($crate::StatusCode::UNEXPECTED_NULL) => { Loading @@ -913,19 +913,19 @@ macro_rules! declare_binder_interface { } } fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> $crate::Result<()> { fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> { self.0.dump(file, args) } fn get_class() -> $crate::InterfaceClass { fn get_class() -> $crate::binder_impl::InterfaceClass { static CLASS_INIT: std::sync::Once = std::sync::Once::new(); static mut CLASS: Option<$crate::InterfaceClass> = None; static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None; CLASS_INIT.call_once(|| unsafe { // Safety: This assignment is guarded by the `CLASS_INIT` `Once` // variable, and therefore is thread-safe, as it can only occur // once. CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>()); CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>()); }); unsafe { // Safety: The `CLASS` variable can only be mutated once, above, Loading @@ -936,25 +936,25 @@ macro_rules! declare_binder_interface { } impl $crate::FromIBinder for dyn $interface { fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> { use $crate::AssociateClass; fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> { use $crate::binder_impl::AssociateClass; let existing_class = ibinder.get_class(); if let Some(class) = existing_class { if class != <$native as $crate::Remotable>::get_class() && class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor() if class != <$native as $crate::binder_impl::Remotable>::get_class() && class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor() { // The binder object's descriptor string matches what we // expect. We still need to treat this local or already // associated object as remote, because we can't cast it // into a Rust service object without a matching class // pointer. return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); } } if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) { let service: $crate::Result<$crate::Binder<$native>> = if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) { let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> = std::convert::TryFrom::try_from(ibinder.clone()); if let Ok(service) = service { // We were able to associate with our expected class and Loading @@ -962,7 +962,7 @@ macro_rules! declare_binder_interface { return Ok($crate::Strong::new(Box::new(service))); } else { // Service is remote return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); } } Loading @@ -970,18 +970,18 @@ macro_rules! declare_binder_interface { } } impl $crate::parcel::Serialize for dyn $interface + '_ impl $crate::binder_impl::Serialize for dyn $interface + '_ where dyn $interface: $crate::Interface { fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> { fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 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::BorrowedParcel<'_>) -> $crate::Result<()> { impl $crate::binder_impl::SerializeOption for dyn $interface + '_ { fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { parcel.write(&this.map($crate::Interface::as_binder)) } } Loading @@ -1004,25 +1004,25 @@ macro_rules! declare_binder_interface { $( // Async interface trait implementations. impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> { fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $async_interface<P>>> { use $crate::AssociateClass; fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> { use $crate::binder_impl::AssociateClass; let existing_class = ibinder.get_class(); if let Some(class) = existing_class { if class != <$native as $crate::Remotable>::get_class() && class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor() if class != <$native as $crate::binder_impl::Remotable>::get_class() && class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor() { // The binder object's descriptor string matches what we // expect. We still need to treat this local or already // associated object as remote, because we can't cast it // into a Rust service object without a matching class // pointer. return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); } } if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) { let service: $crate::Result<$crate::Binder<$native>> = if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) { let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> = std::convert::TryFrom::try_from(ibinder.clone()); if let Ok(service) = service { // We were able to associate with our expected class and Loading @@ -1031,7 +1031,7 @@ macro_rules! declare_binder_interface { //return Ok($crate::Strong::new(Box::new(service))); } else { // Service is remote return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); } } Loading @@ -1039,15 +1039,15 @@ macro_rules! declare_binder_interface { } } impl<P: $crate::BinderAsyncPool> $crate::parcel::Serialize for dyn $async_interface<P> + '_ { fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> { impl<P: $crate::BinderAsyncPool> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ { fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 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::BorrowedParcel<'_>) -> $crate::Result<()> { impl<P: $crate::BinderAsyncPool> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ { fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { parcel.write(&this.map($crate::Interface::as_binder)) } } Loading @@ -1067,11 +1067,11 @@ macro_rules! declare_binder_interface { } } impl<P: $crate::BinderAsyncPool> $crate::ToAsyncInterface<P> for dyn $interface { impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface { type Target = dyn $async_interface<P>; } impl<P: $crate::BinderAsyncPool> $crate::ToSyncInterface for dyn $async_interface<P> { impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> { type Target = dyn $interface; } )? Loading Loading @@ -1103,29 +1103,29 @@ macro_rules! declare_binder_enum { } } impl $crate::parcel::Serialize for $enum { fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> { impl $crate::binder_impl::Serialize for $enum { fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { parcel.write(&self.0) } } impl $crate::parcel::SerializeArray for $enum { fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> { impl $crate::binder_impl::SerializeArray for $enum { fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { let v: Vec<$backing> = slice.iter().map(|x| x.0).collect(); <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel) <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel) } } impl $crate::parcel::Deserialize for $enum { fn deserialize(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Self> { impl $crate::binder_impl::Deserialize for $enum { fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> { parcel.read().map(Self) } } impl $crate::parcel::DeserializeArray for $enum { fn deserialize_array(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Option<Vec<Self>>> { impl $crate::binder_impl::DeserializeArray for $enum { fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> { let v: Option<Vec<$backing>> = <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?; <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?; Ok(v.map(|v| v.into_iter().map(Self).collect())) } } Loading libs/binder/rust/src/lib.rs +34 −29 Original line number Diff line number Diff line Loading @@ -101,45 +101,50 @@ mod binder; mod binder_async; mod error; mod native; mod parcel; mod state; use binder_ndk_sys as sys; pub mod parcel; pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak}; pub use crate::binder_async::{BinderAsyncPool, BoxFuture}; pub use error::{ExceptionCode, Status, StatusCode}; pub use native::{ add_service, force_lazy_services_persist, is_handling_transaction, register_lazy_service, }; pub use parcel::{ParcelFileDescriptor, Parcelable, ParcelableHolder}; pub use proxy::{ get_interface, get_service, wait_for_interface, wait_for_service, DeathRecipient, SpIBinder, WpIBinder, }; pub use state::{ProcessState, ThreadState}; /// Binder result containing a [`Status`] on error. pub type Result<T> = std::result::Result<T, Status>; /// Advanced Binder APIs needed internally by AIDL or when manually using Binder /// without AIDL. pub mod binder_impl { pub use crate::binder::{ BinderFeatures, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable, Stability, Strong, ToAsyncInterface, ToSyncInterface, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, IBinderInternal, InterfaceClass, Remotable, Stability, ToAsyncInterface, ToSyncInterface, TransactionCode, TransactionFlags, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, }; pub use crate::binder_async::{BoxFuture, BinderAsyncPool, BinderAsyncRuntime}; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; pub use native::{add_service, force_lazy_services_persist, is_handling_transaction, register_lazy_service, Binder}; 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}; pub use crate::binder_async::BinderAsyncRuntime; pub use crate::error::status_t; pub use crate::native::Binder; pub use crate::parcel::{ BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Parcel, ParcelableMetadata, Serialize, SerializeArray, SerializeOption, NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG, }; pub use crate::proxy::{AssociateClass, Proxy}; } /// Unstable, in-development API that only allowlisted clients are allowed to use. #[doc(hidden)] pub mod unstable_api { pub use crate::binder::AsNative; pub use crate::proxy::unstable_api::new_spibinder; pub use crate::sys::AIBinder; } /// The public API usable outside AIDL-generated interface crates. pub mod public_api { pub use super::parcel::{ParcelFileDescriptor, ParcelableHolder}; pub use super::{ add_service, force_lazy_services_persist, get_interface, register_lazy_service, wait_for_interface, }; pub use super::{ BinderAsyncPool, BinderFeatures, BoxFuture, DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder, Status, StatusCode, Strong, ThreadState, Weak, WpIBinder, }; /// Binder result containing a [`Status`] on error. pub type Result<T> = std::result::Result<T, Status>; } libs/binder/rust/src/parcel/parcelable.rs +30 −33 File changed.Preview size limit exceeded, changes collapsed. Show changes libs/binder/rust/src/parcel/parcelable_holder.rs +6 −6 Original line number Diff line number Diff line Loading @@ -15,8 +15,8 @@ */ use crate::binder::Stability; use crate::error::{Result, StatusCode}; use crate::parcel::{Parcel, BorrowedParcel, Parcelable}; use crate::error::StatusCode; use crate::parcel::{BorrowedParcel, Parcel, Parcelable}; use crate::{impl_deserialize_for_parcelable, impl_serialize_for_parcelable}; use downcast_rs::{impl_downcast, DowncastSync}; Loading Loading @@ -97,7 +97,7 @@ impl ParcelableHolder { } /// Set the parcelable contained in this `ParcelableHolder`. pub fn set_parcelable<T>(&mut self, p: Arc<T>) -> Result<()> pub fn set_parcelable<T>(&mut self, p: Arc<T>) -> Result<(), StatusCode> where T: Any + Parcelable + ParcelableMetadata + std::fmt::Debug + Send + Sync, { Loading Loading @@ -126,7 +126,7 @@ impl ParcelableHolder { /// * `Ok(None)` if the holder is empty or the descriptor does not match /// * `Ok(Some(_))` if the object holds a parcelable of type `T` /// with the correct descriptor pub fn get_parcelable<T>(&self) -> Result<Option<Arc<T>>> pub fn get_parcelable<T>(&self) -> Result<Option<Arc<T>>, StatusCode> where T: Any + Parcelable + ParcelableMetadata + Default + std::fmt::Debug + Send + Sync, { Loading Loading @@ -180,7 +180,7 @@ impl_serialize_for_parcelable!(ParcelableHolder); impl_deserialize_for_parcelable!(ParcelableHolder); impl Parcelable for ParcelableHolder { fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> { fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<(), StatusCode> { parcel.write(&self.stability)?; let mut data = self.data.lock().unwrap(); Loading Loading @@ -219,7 +219,7 @@ impl Parcelable for ParcelableHolder { } } fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> { fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<(), StatusCode> { self.stability = parcel.read()?; let data_size: i32 = parcel.read()?; Loading Loading
libs/binder/rust/binder_tokio/lib.rs +6 −6 Original line number Diff line number Diff line Loading @@ -28,8 +28,8 @@ //! //! [`Tokio`]: crate::Tokio use binder::public_api::{BinderAsyncPool, BoxFuture, Strong}; use binder::{FromIBinder, StatusCode, BinderAsyncRuntime}; use binder::{BinderAsyncPool, BoxFuture, FromIBinder, StatusCode, Strong}; use binder::binder_impl::BinderAsyncRuntime; use std::future::Future; /// Retrieve an existing service for a particular interface, sleeping for a few Loading @@ -37,12 +37,12 @@ use std::future::Future; pub async fn get_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Result<Strong<T>, StatusCode> { if binder::is_handling_transaction() { // See comment in the BinderAsyncPool impl. return binder::public_api::get_interface::<T>(name); return binder::get_interface::<T>(name); } let name = name.to_string(); let res = tokio::task::spawn_blocking(move || { binder::public_api::get_interface::<T>(&name) binder::get_interface::<T>(&name) }).await; // The `is_panic` branch is not actually reachable in Android as we compile Loading @@ -61,12 +61,12 @@ pub async fn get_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Res pub async fn wait_for_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Result<Strong<T>, StatusCode> { if binder::is_handling_transaction() { // See comment in the BinderAsyncPool impl. return binder::public_api::wait_for_interface::<T>(name); return binder::wait_for_interface::<T>(name); } let name = name.to_string(); let res = tokio::task::spawn_blocking(move || { binder::public_api::wait_for_interface::<T>(&name) binder::wait_for_interface::<T>(&name) }).await; // The `is_panic` branch is not actually reachable in Android as we compile Loading
libs/binder/rust/src/binder.rs +53 −53 Original line number Diff line number Diff line Loading @@ -536,13 +536,13 @@ impl<I: FromIBinder + ?Sized> Eq for Weak<I> {} /// ``` macro_rules! binder_fn_get_class { ($class:ty) => { binder_fn_get_class!($crate::InterfaceClass::new::<$class>()); binder_fn_get_class!($crate::binder_impl::InterfaceClass::new::<$class>()); }; ($constructor:expr) => { fn get_class() -> $crate::InterfaceClass { fn get_class() -> $crate::binder_impl::InterfaceClass { static CLASS_INIT: std::sync::Once = std::sync::Once::new(); static mut CLASS: Option<$crate::InterfaceClass> = None; static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None; CLASS_INIT.call_once(|| unsafe { // Safety: This assignment is guarded by the `CLASS_INIT` `Once` Loading Loading @@ -772,7 +772,7 @@ macro_rules! declare_binder_interface { native: $native($on_transact), proxy: $proxy {}, $(async: $async_interface,)? stability: $crate::Stability::default(), stability: $crate::binder_impl::Stability::default(), } } }; Loading Loading @@ -811,7 +811,7 @@ macro_rules! declare_binder_interface { $($fname: $fty = $finit),* }, $(async: $async_interface,)? stability: $crate::Stability::default(), stability: $crate::binder_impl::Stability::default(), } } }; Loading @@ -828,9 +828,9 @@ macro_rules! declare_binder_interface { } => { $crate::declare_binder_interface! { $interface[$descriptor] { @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")] @doc[concat!("A binder [`Remotable`]($crate::binder_impl::Remotable) that holds an [`", stringify!($interface), "`] object.")] native: $native($on_transact), @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")] @doc[concat!("A binder [`Proxy`]($crate::binder_impl::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")] proxy: $proxy { $($fname: $fty = $finit),* }, Loading Loading @@ -867,7 +867,7 @@ macro_rules! declare_binder_interface { } } impl $crate::Proxy for $proxy impl $crate::binder_impl::Proxy for $proxy where $proxy: $interface, { Loading @@ -875,7 +875,7 @@ macro_rules! declare_binder_interface { $descriptor } fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> { fn from_binder(mut binder: $crate::SpIBinder) -> std::result::Result<Self, $crate::StatusCode> { Ok(Self { binder, $($fname: $finit),* }) } } Loading @@ -887,19 +887,19 @@ macro_rules! declare_binder_interface { impl $native { /// Create a new binder service. pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> { let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability); let mut binder = $crate::binder_impl::Binder::new_with_stability($native(Box::new(inner)), $stability); #[cfg(not(android_vndk))] $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); $crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid); $crate::Strong::new(Box::new(binder)) } } impl $crate::Remotable for $native { impl $crate::binder_impl::Remotable for $native { fn get_descriptor() -> &'static str { $descriptor } fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::BorrowedParcel<'_>, reply: &mut $crate::BorrowedParcel<'_>) -> $crate::Result<()> { fn on_transact(&self, code: $crate::binder_impl::TransactionCode, data: &$crate::binder_impl::BorrowedParcel<'_>, reply: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { match $on_transact(&*self.0, code, data, reply) { // The C++ backend converts UNEXPECTED_NULL into an exception Err($crate::StatusCode::UNEXPECTED_NULL) => { Loading @@ -913,19 +913,19 @@ macro_rules! declare_binder_interface { } } fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> $crate::Result<()> { fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> std::result::Result<(), $crate::StatusCode> { self.0.dump(file, args) } fn get_class() -> $crate::InterfaceClass { fn get_class() -> $crate::binder_impl::InterfaceClass { static CLASS_INIT: std::sync::Once = std::sync::Once::new(); static mut CLASS: Option<$crate::InterfaceClass> = None; static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None; CLASS_INIT.call_once(|| unsafe { // Safety: This assignment is guarded by the `CLASS_INIT` `Once` // variable, and therefore is thread-safe, as it can only occur // once. CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>()); CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>()); }); unsafe { // Safety: The `CLASS` variable can only be mutated once, above, Loading @@ -936,25 +936,25 @@ macro_rules! declare_binder_interface { } impl $crate::FromIBinder for dyn $interface { fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> { use $crate::AssociateClass; fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $interface>, $crate::StatusCode> { use $crate::binder_impl::AssociateClass; let existing_class = ibinder.get_class(); if let Some(class) = existing_class { if class != <$native as $crate::Remotable>::get_class() && class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor() if class != <$native as $crate::binder_impl::Remotable>::get_class() && class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor() { // The binder object's descriptor string matches what we // expect. We still need to treat this local or already // associated object as remote, because we can't cast it // into a Rust service object without a matching class // pointer. return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); } } if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) { let service: $crate::Result<$crate::Binder<$native>> = if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) { let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> = std::convert::TryFrom::try_from(ibinder.clone()); if let Ok(service) = service { // We were able to associate with our expected class and Loading @@ -962,7 +962,7 @@ macro_rules! declare_binder_interface { return Ok($crate::Strong::new(Box::new(service))); } else { // Service is remote return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); } } Loading @@ -970,18 +970,18 @@ macro_rules! declare_binder_interface { } } impl $crate::parcel::Serialize for dyn $interface + '_ impl $crate::binder_impl::Serialize for dyn $interface + '_ where dyn $interface: $crate::Interface { fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> { fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 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::BorrowedParcel<'_>) -> $crate::Result<()> { impl $crate::binder_impl::SerializeOption for dyn $interface + '_ { fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { parcel.write(&this.map($crate::Interface::as_binder)) } } Loading @@ -1004,25 +1004,25 @@ macro_rules! declare_binder_interface { $( // Async interface trait implementations. impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> { fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $async_interface<P>>> { use $crate::AssociateClass; fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> { use $crate::binder_impl::AssociateClass; let existing_class = ibinder.get_class(); if let Some(class) = existing_class { if class != <$native as $crate::Remotable>::get_class() && class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor() if class != <$native as $crate::binder_impl::Remotable>::get_class() && class.get_descriptor() == <$native as $crate::binder_impl::Remotable>::get_descriptor() { // The binder object's descriptor string matches what we // expect. We still need to treat this local or already // associated object as remote, because we can't cast it // into a Rust service object without a matching class // pointer. return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); } } if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) { let service: $crate::Result<$crate::Binder<$native>> = if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) { let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> = std::convert::TryFrom::try_from(ibinder.clone()); if let Ok(service) = service { // We were able to associate with our expected class and Loading @@ -1031,7 +1031,7 @@ macro_rules! declare_binder_interface { //return Ok($crate::Strong::new(Box::new(service))); } else { // Service is remote return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))); return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?))); } } Loading @@ -1039,15 +1039,15 @@ macro_rules! declare_binder_interface { } } impl<P: $crate::BinderAsyncPool> $crate::parcel::Serialize for dyn $async_interface<P> + '_ { fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> { impl<P: $crate::BinderAsyncPool> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ { fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { 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::BorrowedParcel<'_>) -> $crate::Result<()> { impl<P: $crate::BinderAsyncPool> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ { fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { parcel.write(&this.map($crate::Interface::as_binder)) } } Loading @@ -1067,11 +1067,11 @@ macro_rules! declare_binder_interface { } } impl<P: $crate::BinderAsyncPool> $crate::ToAsyncInterface<P> for dyn $interface { impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface { type Target = dyn $async_interface<P>; } impl<P: $crate::BinderAsyncPool> $crate::ToSyncInterface for dyn $async_interface<P> { impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> { type Target = dyn $interface; } )? Loading Loading @@ -1103,29 +1103,29 @@ macro_rules! declare_binder_enum { } } impl $crate::parcel::Serialize for $enum { fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> { impl $crate::binder_impl::Serialize for $enum { fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { parcel.write(&self.0) } } impl $crate::parcel::SerializeArray for $enum { fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> { impl $crate::binder_impl::SerializeArray for $enum { fn serialize_array(slice: &[Self], parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> { let v: Vec<$backing> = slice.iter().map(|x| x.0).collect(); <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel) <$backing as $crate::binder_impl::SerializeArray>::serialize_array(&v[..], parcel) } } impl $crate::parcel::Deserialize for $enum { fn deserialize(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Self> { impl $crate::binder_impl::Deserialize for $enum { fn deserialize(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Self, $crate::StatusCode> { parcel.read().map(Self) } } impl $crate::parcel::DeserializeArray for $enum { fn deserialize_array(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Option<Vec<Self>>> { impl $crate::binder_impl::DeserializeArray for $enum { fn deserialize_array(parcel: &$crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<Option<Vec<Self>>, $crate::StatusCode> { let v: Option<Vec<$backing>> = <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?; <$backing as $crate::binder_impl::DeserializeArray>::deserialize_array(parcel)?; Ok(v.map(|v| v.into_iter().map(Self).collect())) } } Loading
libs/binder/rust/src/lib.rs +34 −29 Original line number Diff line number Diff line Loading @@ -101,45 +101,50 @@ mod binder; mod binder_async; mod error; mod native; mod parcel; mod state; use binder_ndk_sys as sys; pub mod parcel; pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak}; pub use crate::binder_async::{BinderAsyncPool, BoxFuture}; pub use error::{ExceptionCode, Status, StatusCode}; pub use native::{ add_service, force_lazy_services_persist, is_handling_transaction, register_lazy_service, }; pub use parcel::{ParcelFileDescriptor, Parcelable, ParcelableHolder}; pub use proxy::{ get_interface, get_service, wait_for_interface, wait_for_service, DeathRecipient, SpIBinder, WpIBinder, }; pub use state::{ProcessState, ThreadState}; /// Binder result containing a [`Status`] on error. pub type Result<T> = std::result::Result<T, Status>; /// Advanced Binder APIs needed internally by AIDL or when manually using Binder /// without AIDL. pub mod binder_impl { pub use crate::binder::{ BinderFeatures, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable, Stability, Strong, ToAsyncInterface, ToSyncInterface, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, IBinderInternal, InterfaceClass, Remotable, Stability, ToAsyncInterface, ToSyncInterface, TransactionCode, TransactionFlags, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION, }; pub use crate::binder_async::{BoxFuture, BinderAsyncPool, BinderAsyncRuntime}; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; pub use native::{add_service, force_lazy_services_persist, is_handling_transaction, register_lazy_service, Binder}; 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}; pub use crate::binder_async::BinderAsyncRuntime; pub use crate::error::status_t; pub use crate::native::Binder; pub use crate::parcel::{ BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Parcel, ParcelableMetadata, Serialize, SerializeArray, SerializeOption, NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG, }; pub use crate::proxy::{AssociateClass, Proxy}; } /// Unstable, in-development API that only allowlisted clients are allowed to use. #[doc(hidden)] pub mod unstable_api { pub use crate::binder::AsNative; pub use crate::proxy::unstable_api::new_spibinder; pub use crate::sys::AIBinder; } /// The public API usable outside AIDL-generated interface crates. pub mod public_api { pub use super::parcel::{ParcelFileDescriptor, ParcelableHolder}; pub use super::{ add_service, force_lazy_services_persist, get_interface, register_lazy_service, wait_for_interface, }; pub use super::{ BinderAsyncPool, BinderFeatures, BoxFuture, DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder, Status, StatusCode, Strong, ThreadState, Weak, WpIBinder, }; /// Binder result containing a [`Status`] on error. pub type Result<T> = std::result::Result<T, Status>; }
libs/binder/rust/src/parcel/parcelable.rs +30 −33 File changed.Preview size limit exceeded, changes collapsed. Show changes
libs/binder/rust/src/parcel/parcelable_holder.rs +6 −6 Original line number Diff line number Diff line Loading @@ -15,8 +15,8 @@ */ use crate::binder::Stability; use crate::error::{Result, StatusCode}; use crate::parcel::{Parcel, BorrowedParcel, Parcelable}; use crate::error::StatusCode; use crate::parcel::{BorrowedParcel, Parcel, Parcelable}; use crate::{impl_deserialize_for_parcelable, impl_serialize_for_parcelable}; use downcast_rs::{impl_downcast, DowncastSync}; Loading Loading @@ -97,7 +97,7 @@ impl ParcelableHolder { } /// Set the parcelable contained in this `ParcelableHolder`. pub fn set_parcelable<T>(&mut self, p: Arc<T>) -> Result<()> pub fn set_parcelable<T>(&mut self, p: Arc<T>) -> Result<(), StatusCode> where T: Any + Parcelable + ParcelableMetadata + std::fmt::Debug + Send + Sync, { Loading Loading @@ -126,7 +126,7 @@ impl ParcelableHolder { /// * `Ok(None)` if the holder is empty or the descriptor does not match /// * `Ok(Some(_))` if the object holds a parcelable of type `T` /// with the correct descriptor pub fn get_parcelable<T>(&self) -> Result<Option<Arc<T>>> pub fn get_parcelable<T>(&self) -> Result<Option<Arc<T>>, StatusCode> where T: Any + Parcelable + ParcelableMetadata + Default + std::fmt::Debug + Send + Sync, { Loading Loading @@ -180,7 +180,7 @@ impl_serialize_for_parcelable!(ParcelableHolder); impl_deserialize_for_parcelable!(ParcelableHolder); impl Parcelable for ParcelableHolder { fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> { fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<(), StatusCode> { parcel.write(&self.stability)?; let mut data = self.data.lock().unwrap(); Loading Loading @@ -219,7 +219,7 @@ impl Parcelable for ParcelableHolder { } } fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> { fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<(), StatusCode> { self.stability = parcel.read()?; let data_size: i32 = parcel.read()?; Loading