diff options
| -rw-r--r-- | cmds/servicemanager/ServiceManager.cpp | 4 | ||||
| -rw-r--r-- | data/etc/Android.bp | 6 | ||||
| -rw-r--r-- | libs/binder/include/binder/IInterface.h | 34 | ||||
| -rw-r--r-- | libs/binder/rust/binder_tokio/lib.rs | 12 | ||||
| -rw-r--r-- | libs/binder/rust/src/binder.rs | 106 | ||||
| -rw-r--r-- | libs/binder/rust/src/lib.rs | 63 | ||||
| -rw-r--r-- | libs/binder/rust/src/parcel/parcelable.rs | 63 | ||||
| -rw-r--r-- | libs/binder/rust/src/parcel/parcelable_holder.rs | 12 | ||||
| -rw-r--r-- | libs/binder/rust/tests/integration.rs | 84 | ||||
| -rw-r--r-- | libs/binder/rust/tests/serialization.rs | 9 |
10 files changed, 203 insertions, 190 deletions
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp index 4374abe2ef..555be1ed7e 100644 --- a/cmds/servicemanager/ServiceManager.cpp +++ b/cmds/servicemanager/ServiceManager.cpp @@ -113,8 +113,8 @@ static bool isVintfDeclared(const std::string& name) { if (!found) { // Although it is tested, explicitly rebuilding qualified name, in case it // becomes something unexpected. - LOG(ERROR) << "Could not find " << aname.package << "." << aname.iface << "/" - << aname.instance << " in the VINTF manifest."; + LOG(INFO) << "Could not find " << aname.package << "." << aname.iface << "/" + << aname.instance << " in the VINTF manifest."; } return found; diff --git a/data/etc/Android.bp b/data/etc/Android.bp index 931c5e3f2a..1be3a69a7d 100644 --- a/data/etc/Android.bp +++ b/data/etc/Android.bp @@ -191,6 +191,12 @@ prebuilt_etc { } prebuilt_etc { + name: "android.hardware.wifi.direct.prebuilt.xml", + src: "android.hardware.wifi.direct.xml", + defaults: ["frameworks_native_data_etc_defaults"], +} + +prebuilt_etc { name: "android.hardware.wifi.passpoint.prebuilt.xml", src: "android.hardware.wifi.passpoint.xml", defaults: ["frameworks_native_data_etc_defaults"], diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h index 7d14315b01..f295417ab2 100644 --- a/libs/binder/include/binder/IInterface.h +++ b/libs/binder/include/binder/IInterface.h @@ -93,20 +93,20 @@ protected: // ---------------------------------------------------------------------- -#define DECLARE_META_INTERFACE(INTERFACE) \ -public: \ - static const ::android::String16 descriptor; \ - static ::android::sp<I##INTERFACE> asInterface( \ - const ::android::sp<::android::IBinder>& obj); \ - virtual const ::android::String16& getInterfaceDescriptor() const; \ - I##INTERFACE(); \ - virtual ~I##INTERFACE(); \ - static bool setDefaultImpl(std::unique_ptr<I##INTERFACE> impl); \ - static const std::unique_ptr<I##INTERFACE>& getDefaultImpl(); \ -private: \ - static std::unique_ptr<I##INTERFACE> default_impl; \ -public: \ - +#define DECLARE_META_INTERFACE(INTERFACE) \ +public: \ + static const ::android::String16 descriptor; \ + static ::android::sp<I##INTERFACE> asInterface(const ::android::sp<::android::IBinder>& obj); \ + virtual const ::android::String16& getInterfaceDescriptor() const; \ + I##INTERFACE(); \ + virtual ~I##INTERFACE(); \ + static bool setDefaultImpl(::android::sp<I##INTERFACE> impl); \ + static const ::android::sp<I##INTERFACE>& getDefaultImpl(); \ + \ +private: \ + static ::android::sp<I##INTERFACE> default_impl; \ + \ +public: #define __IINTF_CONCAT(x, y) (x ## y) @@ -142,8 +142,8 @@ public: \ } \ return intr; \ } \ - std::unique_ptr<ITYPE> ITYPE::default_impl; \ - bool ITYPE::setDefaultImpl(std::unique_ptr<ITYPE> impl) { \ + ::android::sp<ITYPE> ITYPE::default_impl; \ + bool ITYPE::setDefaultImpl(::android::sp<ITYPE> impl) { \ /* Only one user of this interface can use this function */ \ /* at a time. This is a heuristic to detect if two different */ \ /* users in the same process use this function. */ \ @@ -154,7 +154,7 @@ public: \ } \ return false; \ } \ - const std::unique_ptr<ITYPE>& ITYPE::getDefaultImpl() { return ITYPE::default_impl; } \ + const ::android::sp<ITYPE>& ITYPE::getDefaultImpl() { return ITYPE::default_impl; } \ ITYPE::INAME() {} \ ITYPE::~INAME() {} diff --git a/libs/binder/rust/binder_tokio/lib.rs b/libs/binder/rust/binder_tokio/lib.rs index 47dcdc2bc3..9dcef4260e 100644 --- a/libs/binder/rust/binder_tokio/lib.rs +++ b/libs/binder/rust/binder_tokio/lib.rs @@ -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 @@ -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 @@ -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 diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs index 4d6b294000..7895a7293d 100644 --- a/libs/binder/rust/src/binder.rs +++ b/libs/binder/rust/src/binder.rs @@ -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` @@ -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(), } } }; @@ -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(), } } }; @@ -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),* }, @@ -867,7 +867,7 @@ macro_rules! declare_binder_interface { } } - impl $crate::Proxy for $proxy + impl $crate::binder_impl::Proxy for $proxy where $proxy: $interface, { @@ -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),* }) } } @@ -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) => { @@ -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, @@ -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 @@ -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)?))); } } @@ -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)) } } @@ -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 @@ -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)?))); } } @@ -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)) } } @@ -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; } )? @@ -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())) } } diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs index 20d90f7b3c..1d7de98c0d 100644 --- a/libs/binder/rust/src/lib.rs +++ b/libs/binder/rust/src/lib.rs @@ -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 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, +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 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}; +/// 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::{ + 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::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>; -} diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs index 61f88b6cce..0c7e48df0c 100644 --- a/libs/binder/rust/src/parcel/parcelable.rs +++ b/libs/binder/rust/src/parcel/parcelable.rs @@ -802,35 +802,32 @@ impl<T: DeserializeOption> Deserialize for Option<T> { #[macro_export] macro_rules! impl_serialize_for_parcelable { ($parcelable:ident) => { - impl $crate::parcel::Serialize for $parcelable { + impl $crate::binder_impl::Serialize for $parcelable { fn serialize( &self, - parcel: &mut $crate::parcel::BorrowedParcel<'_>, - ) -> $crate::Result<()> { - <Self as $crate::parcel::SerializeOption>::serialize_option( - Some(self), - parcel, - ) + parcel: &mut $crate::binder_impl::BorrowedParcel<'_>, + ) -> std::result::Result<(), $crate::StatusCode> { + <Self as $crate::binder_impl::SerializeOption>::serialize_option(Some(self), parcel) } } - impl $crate::parcel::SerializeArray for $parcelable {} + impl $crate::binder_impl::SerializeArray for $parcelable {} - impl $crate::parcel::SerializeOption for $parcelable { + impl $crate::binder_impl::SerializeOption for $parcelable { fn serialize_option( this: Option<&Self>, - parcel: &mut $crate::parcel::BorrowedParcel<'_>, - ) -> $crate::Result<()> { + parcel: &mut $crate::binder_impl::BorrowedParcel<'_>, + ) -> std::result::Result<(), $crate::StatusCode> { if let Some(this) = this { - use $crate::parcel::Parcelable; - parcel.write(&$crate::parcel::NON_NULL_PARCELABLE_FLAG)?; + use $crate::Parcelable; + parcel.write(&$crate::binder_impl::NON_NULL_PARCELABLE_FLAG)?; this.write_to_parcel(parcel) } else { - parcel.write(&$crate::parcel::NULL_PARCELABLE_FLAG) + parcel.write(&$crate::binder_impl::NULL_PARCELABLE_FLAG) } } } - } + }; } /// Implement `Deserialize` trait and friends for a parcelable @@ -842,54 +839,54 @@ macro_rules! impl_serialize_for_parcelable { #[macro_export] macro_rules! impl_deserialize_for_parcelable { ($parcelable:ident) => { - impl $crate::parcel::Deserialize for $parcelable { + impl $crate::binder_impl::Deserialize for $parcelable { fn deserialize( - parcel: &$crate::parcel::BorrowedParcel<'_>, - ) -> $crate::Result<Self> { - $crate::parcel::DeserializeOption::deserialize_option(parcel) + parcel: &$crate::binder_impl::BorrowedParcel<'_>, + ) -> std::result::Result<Self, $crate::StatusCode> { + $crate::binder_impl::DeserializeOption::deserialize_option(parcel) .transpose() .unwrap_or(Err($crate::StatusCode::UNEXPECTED_NULL)) } fn deserialize_from( &mut self, - parcel: &$crate::parcel::BorrowedParcel<'_>, - ) -> $crate::Result<()> { + parcel: &$crate::binder_impl::BorrowedParcel<'_>, + ) -> std::result::Result<(), $crate::StatusCode> { let status: i32 = parcel.read()?; - if status == $crate::parcel::NULL_PARCELABLE_FLAG { + if status == $crate::binder_impl::NULL_PARCELABLE_FLAG { Err($crate::StatusCode::UNEXPECTED_NULL) } else { - use $crate::parcel::Parcelable; + use $crate::Parcelable; self.read_from_parcel(parcel) } } } - impl $crate::parcel::DeserializeArray for $parcelable {} + impl $crate::binder_impl::DeserializeArray for $parcelable {} - impl $crate::parcel::DeserializeOption for $parcelable { + impl $crate::binder_impl::DeserializeOption for $parcelable { fn deserialize_option( - parcel: &$crate::parcel::BorrowedParcel<'_>, - ) -> $crate::Result<Option<Self>> { + parcel: &$crate::binder_impl::BorrowedParcel<'_>, + ) -> std::result::Result<Option<Self>, $crate::StatusCode> { let mut result = None; Self::deserialize_option_from(&mut result, parcel)?; Ok(result) } fn deserialize_option_from( this: &mut Option<Self>, - parcel: &$crate::parcel::BorrowedParcel<'_>, - ) -> $crate::Result<()> { + parcel: &$crate::binder_impl::BorrowedParcel<'_>, + ) -> std::result::Result<(), $crate::StatusCode> { let status: i32 = parcel.read()?; - if status == $crate::parcel::NULL_PARCELABLE_FLAG { + if status == $crate::binder_impl::NULL_PARCELABLE_FLAG { *this = None; Ok(()) } else { - use $crate::parcel::Parcelable; + use $crate::Parcelable; this.get_or_insert_with(Self::default) .read_from_parcel(parcel) } } } - } + }; } impl<T: Serialize> Serialize for Box<T> { @@ -918,7 +915,7 @@ impl<T: DeserializeOption> DeserializeOption for Box<T> { #[cfg(test)] mod tests { - use crate::Parcel; + use crate::parcel::Parcel; use super::*; #[test] diff --git a/libs/binder/rust/src/parcel/parcelable_holder.rs b/libs/binder/rust/src/parcel/parcelable_holder.rs index b4282b2ec8..bc70ea6c30 100644 --- a/libs/binder/rust/src/parcel/parcelable_holder.rs +++ b/libs/binder/rust/src/parcel/parcelable_holder.rs @@ -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}; @@ -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, { @@ -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, { @@ -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(); @@ -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()?; diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs index 80dc47682c..50daf1c0cc 100644 --- a/libs/binder/rust/tests/integration.rs +++ b/libs/binder/rust/tests/integration.rs @@ -17,11 +17,13 @@ //! Rust Binder crate integration tests use binder::{declare_binder_enum, declare_binder_interface}; -use binder::parcel::BorrowedParcel; -use binder::{ - Binder, BinderFeatures, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode, - FIRST_CALL_TRANSACTION, +use binder::{BinderFeatures, Interface, StatusCode, ThreadState}; +// Import from internal API for testing only, do not use this module in +// production. +use binder::binder_impl::{ + Binder, BorrowedParcel, IBinderInternal, TransactionCode, FIRST_CALL_TRANSACTION, }; + use std::convert::{TryFrom, TryInto}; use std::ffi::CStr; use std::fs::File; @@ -120,7 +122,7 @@ impl TryFrom<u32> for TestTransactionCode { } impl Interface for TestService { - fn dump(&self, _file: &File, args: &[&CStr]) -> binder::Result<()> { + fn dump(&self, _file: &File, args: &[&CStr]) -> Result<(), StatusCode> { let mut dump_args = self.dump_args.lock().unwrap(); dump_args.extend(args.iter().map(|s| s.to_str().unwrap().to_owned())); Ok(()) @@ -128,22 +130,22 @@ impl Interface for TestService { } impl ITest for TestService { - fn test(&self) -> binder::Result<String> { + fn test(&self) -> Result<String, StatusCode> { Ok(self.s.clone()) } - fn get_dump_args(&self) -> binder::Result<Vec<String>> { + fn get_dump_args(&self) -> Result<Vec<String>, StatusCode> { let args = self.dump_args.lock().unwrap().clone(); Ok(args) } - fn get_selinux_context(&self) -> binder::Result<String> { + fn get_selinux_context(&self) -> Result<String, StatusCode> { let sid = ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned())); sid.ok_or(StatusCode::UNEXPECTED_NULL) } - fn get_is_handling_transaction(&self) -> binder::Result<bool> { + fn get_is_handling_transaction(&self) -> Result<bool, StatusCode> { Ok(binder::is_handling_transaction()) } } @@ -151,31 +153,31 @@ impl ITest for TestService { /// Trivial testing binder interface pub trait ITest: Interface { /// Returns a test string - fn test(&self) -> binder::Result<String>; + fn test(&self) -> Result<String, StatusCode>; /// Return the arguments sent via dump - fn get_dump_args(&self) -> binder::Result<Vec<String>>; + fn get_dump_args(&self) -> Result<Vec<String>, StatusCode>; /// Returns the caller's SELinux context - fn get_selinux_context(&self) -> binder::Result<String>; + fn get_selinux_context(&self) -> Result<String, StatusCode>; /// Returns the value of calling `is_handling_transaction`. - fn get_is_handling_transaction(&self) -> binder::Result<bool>; + fn get_is_handling_transaction(&self) -> Result<bool, StatusCode>; } /// Async trivial testing binder interface pub trait IATest<P>: Interface { /// Returns a test string - fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>>; + fn test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>; /// Return the arguments sent via dump - fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>>; + fn get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>>; /// Returns the caller's SELinux context - fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>>; + fn get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>>; /// Returns the value of calling `is_handling_transaction`. - fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>>; + fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>>; } declare_binder_interface! { @@ -193,7 +195,7 @@ fn on_transact( code: TransactionCode, _data: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>, -) -> binder::Result<()> { +) -> Result<(), StatusCode> { match code.try_into()? { TestTransactionCode::Test => reply.write(&service.test()?), TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?), @@ -203,21 +205,21 @@ fn on_transact( } impl ITest for BpTest { - fn test(&self) -> binder::Result<String> { + fn test(&self) -> Result<String, StatusCode> { let reply = self.binder .transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(()))?; reply.read() } - fn get_dump_args(&self) -> binder::Result<Vec<String>> { + fn get_dump_args(&self) -> Result<Vec<String>, StatusCode> { let reply = self.binder .transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(()))?; reply.read() } - fn get_selinux_context(&self) -> binder::Result<String> { + fn get_selinux_context(&self) -> Result<String, StatusCode> { let reply = self.binder.transact( TestTransactionCode::GetSelinuxContext as TransactionCode, 0, @@ -226,7 +228,7 @@ impl ITest for BpTest { reply.read() } - fn get_is_handling_transaction(&self) -> binder::Result<bool> { + fn get_is_handling_transaction(&self) -> Result<bool, StatusCode> { let reply = self.binder.transact( TestTransactionCode::GetIsHandlingTransaction as TransactionCode, 0, @@ -237,7 +239,7 @@ impl ITest for BpTest { } impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { - fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>> { + fn test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>> { let binder = self.binder.clone(); P::spawn( move || binder.transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(())), @@ -245,7 +247,7 @@ impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { ) } - fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>> { + fn get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>> { let binder = self.binder.clone(); P::spawn( move || binder.transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(())), @@ -253,7 +255,7 @@ impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { ) } - fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>> { + fn get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>> { let binder = self.binder.clone(); P::spawn( move || binder.transact(TestTransactionCode::GetSelinuxContext as TransactionCode, 0, |_| Ok(())), @@ -261,7 +263,7 @@ impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { ) } - fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>> { + fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>> { let binder = self.binder.clone(); P::spawn( move || binder.transact(TestTransactionCode::GetIsHandlingTransaction as TransactionCode, 0, |_| Ok(())), @@ -271,40 +273,40 @@ impl<P: binder::BinderAsyncPool> IATest<P> for BpTest { } impl ITest for Binder<BnTest> { - fn test(&self) -> binder::Result<String> { + fn test(&self) -> Result<String, StatusCode> { self.0.test() } - fn get_dump_args(&self) -> binder::Result<Vec<String>> { + fn get_dump_args(&self) -> Result<Vec<String>, StatusCode> { self.0.get_dump_args() } - fn get_selinux_context(&self) -> binder::Result<String> { + fn get_selinux_context(&self) -> Result<String, StatusCode> { self.0.get_selinux_context() } - fn get_is_handling_transaction(&self) -> binder::Result<bool> { + fn get_is_handling_transaction(&self) -> Result<bool, StatusCode> { self.0.get_is_handling_transaction() } } impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> { - fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>> { + fn test(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>> { let res = self.0.test(); Box::pin(async move { res }) } - fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>> { + fn get_dump_args(&self) -> binder::BoxFuture<'static, Result<Vec<String>, StatusCode>> { let res = self.0.get_dump_args(); Box::pin(async move { res }) } - fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>> { + fn get_selinux_context(&self) -> binder::BoxFuture<'static, Result<String, StatusCode>> { let res = self.0.get_selinux_context(); Box::pin(async move { res }) } - fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, binder::Result<bool>> { + fn get_is_handling_transaction(&self) -> binder::BoxFuture<'static, Result<bool, StatusCode>> { let res = self.0.get_is_handling_transaction(); Box::pin(async move { res }) } @@ -325,7 +327,7 @@ fn on_transact_same_descriptor( _code: TransactionCode, _data: &BorrowedParcel<'_>, _reply: &mut BorrowedParcel<'_>, -) -> binder::Result<()> { +) -> Result<(), StatusCode> { Ok(()) } @@ -363,9 +365,12 @@ mod tests { use std::time::Duration; use binder::{ - Binder, BinderFeatures, DeathRecipient, FromIBinder, IBinder, IBinderInternal, Interface, - SpIBinder, StatusCode, Strong, + BinderFeatures, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode, + Strong, }; + // Import from impl API for testing only, should not be necessary as long as + // you are using AIDL. + use binder::binder_impl::{Binder, IBinderInternal, TransactionCode}; use binder_tokio::Tokio; @@ -743,8 +748,7 @@ mod tests { let _process = ScopedServiceProcess::new(service_name); let test_client: Strong<dyn ITest> = - binder::get_interface(service_name) - .expect("Did not get test binder service"); + binder::get_interface(service_name).expect("Did not get test binder service"); let mut remote = test_client.as_binder(); assert!(remote.is_binder_alive()); remote.ping_binder().expect("Could not ping remote service"); @@ -925,7 +929,7 @@ mod tests { let service2 = service2.as_binder(); let parcel = service1.prepare_transact().unwrap(); - let res = service2.submit_transact(super::TestTransactionCode::Test as binder::TransactionCode, parcel, 0); + let res = service2.submit_transact(super::TestTransactionCode::Test as TransactionCode, parcel, 0); match res { Ok(_) => panic!("submit_transact should fail"), diff --git a/libs/binder/rust/tests/serialization.rs b/libs/binder/rust/tests/serialization.rs index 1fc761e2c8..b62da7be03 100644 --- a/libs/binder/rust/tests/serialization.rs +++ b/libs/binder/rust/tests/serialization.rs @@ -18,11 +18,12 @@ //! access. use binder::declare_binder_interface; -use binder::parcel::ParcelFileDescriptor; use binder::{ - Binder, BinderFeatures, BorrowedParcel, ExceptionCode, Interface, Result, SpIBinder, Status, - StatusCode, TransactionCode, + BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, SpIBinder, Status, StatusCode, }; +// Import from impl API for testing only, should not be necessary as long as you +// are using AIDL. +use binder::binder_impl::{BorrowedParcel, Binder, TransactionCode}; use std::ffi::{c_void, CStr, CString}; use std::sync::Once; @@ -113,7 +114,7 @@ fn on_transact( code: TransactionCode, parcel: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>, -) -> Result<()> { +) -> Result<(), StatusCode> { match code { bindings::Transaction_TEST_BOOL => { assert_eq!(parcel.read::<bool>()?, true); |