#[repr(C)]pub struct Binder<T: Remotable> { /* private fields */ }
Expand description
Rust wrapper around Binder remotable objects.
Implements the C++ BBinder
class, and therefore implements the C++
IBinder
interface.
Implementations§
Source§impl<T: Remotable> Binder<T>
impl<T: Remotable> Binder<T>
Sourcepub fn new(rust_object: T) -> Binder<T>
pub fn new(rust_object: T) -> Binder<T>
Create a new Binder remotable object with default stability
This moves the rust_object
into an owned Box
and Binder will
manage its lifetime.
Sourcepub fn new_with_stability(rust_object: T, stability: Stability) -> Binder<T>
pub fn new_with_stability(rust_object: T, stability: Stability) -> Binder<T>
Create a new Binder remotable object with the given stability
This moves the rust_object
into an owned Box
and Binder will
manage its lifetime.
Sourcepub fn set_extension(
&mut self,
extension: &mut SpIBinder,
) -> Result<(), StatusCode>
pub fn set_extension( &mut self, extension: &mut SpIBinder, ) -> Result<(), StatusCode>
Set the extension of a binder interface. This allows a downstream developer to add an extension to an interface without modifying its interface file. This should be called immediately when the object is created before it is passed to another thread.
§Examples
For instance, imagine if we have this Binder AIDL interface definition: interface IFoo { void doFoo(); }
If an unrelated owner (perhaps in a downstream codebase) wants to make a change to the interface, they have two options:
-
Historical option that has proven to be BAD! Only the original author of an interface should change an interface. If someone downstream wants additional functionality, they should not ever change the interface or use this method.
BAD TO DO: interface IFoo { BAD TO DO BAD TO DO: void doFoo(); BAD TO DO BAD TO DO: + void doBar(); // adding a method BAD TO DO BAD TO DO: } BAD TO DO
-
Option that this method enables! Leave the original interface unchanged (do not change IFoo!). Instead, create a new AIDL interface in a downstream package:
package com.<name>; // new functionality in a new package interface IBar { void doBar(); }
When registering the interface, add:
let mut foo: Binder<MyFoo> = Binder::new(my_foo); // class in AOSP codebase let bar: Binder<MyBar> = Binder::new(my_bar); // custom extension class foo.set_extension(&mut bar.as_binder()); // use method in Binder
Then, clients of
IFoo
can get this extension:if let Some(barBinder) = binder.get_extension()? { let bar = BpBar::new(barBinder) .expect("Extension was not of type IBar"); } else { // There was no extension }
Sourcepub fn get_descriptor() -> &'static str
pub fn get_descriptor() -> &'static str
Retrieve the interface descriptor string for this object’s Binder interface.
Trait Implementations§
Source§impl<T: Remotable> Interface for Binder<T>
impl<T: Remotable> Interface for Binder<T>
Source§impl<B: Remotable> Serialize for Binder<B>
impl<B: Remotable> Serialize for Binder<B>
Source§fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<(), StatusCode>
fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<(), StatusCode>
crate::parcel::Parcel
.Source§impl<B: Remotable> TryFrom<SpIBinder> for Binder<B>
impl<B: Remotable> TryFrom<SpIBinder> for Binder<B>
Source§type Error = android_c_interface_StatusCode
type Error = android_c_interface_StatusCode
impl<T: Remotable> Send for Binder<T>
Safety:
A Binder<T>
is a pair of unique owning pointers to two values:
- a C++ ABBinder which the C++ API guarantees can be passed between threads
- a Rust object which implements
Remotable
; this trait requiresSend + Sync
Both pointers are unique (never escape the Binder<T>
object and are not copied)
so we can essentially treat Binder<T>
as a box-like containing the two objects;
the box-like object inherits Send
from the two inner values, similarly
to how Box<T>
is Send
if T
is Send
.
impl<T: Remotable> Sync for Binder<T>
Safety:
A Binder<T>
is a pair of unique owning pointers to two values:
- a C++ ABBinder which is thread-safe, i.e.
Send + Sync
- a Rust object which implements
Remotable
; this trait requiresSend + Sync
ABBinder
contains an immutable mUserData
pointer, which is actually a
pointer to a boxed T: Remotable
, which is Sync
. ABBinder
also contains
a mutable pointer to its class, but mutation of this field is controlled by
a mutex and it is only allowed to be set once, therefore we can concurrently
access this field safely. ABBinder
inherits from BBinder
, which is also
thread-safe. Thus ABBinder
is thread-safe.
Both pointers are unique (never escape the Binder<T>
object and are not copied)
so we can essentially treat Binder<T>
as a box-like containing the two objects;
the box-like object inherits Sync
from the two inner values, similarly
to how Box<T>
is Sync
if T
is Sync
.
Auto Trait Implementations§
impl<T> Freeze for Binder<T>
impl<T> RefUnwindSafe for Binder<T>where
T: RefUnwindSafe,
impl<T> Unpin for Binder<T>
impl<T> UnwindSafe for Binder<T>where
T: RefUnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IBinder for Twhere
T: AsNative<AIBinder>,
impl<T> IBinder for Twhere
T: AsNative<AIBinder>,
Source§fn link_to_death(
&mut self,
recipient: &mut DeathRecipient,
) -> Result<(), android_c_interface_StatusCode>
fn link_to_death( &mut self, recipient: &mut DeathRecipient, ) -> Result<(), android_c_interface_StatusCode>
DeathRecipient
’s callback will be called. Read moreSource§fn unlink_to_death(
&mut self,
recipient: &mut DeathRecipient,
) -> Result<(), android_c_interface_StatusCode>
fn unlink_to_death( &mut self, recipient: &mut DeathRecipient, ) -> Result<(), android_c_interface_StatusCode>
Source§fn ping_binder(&mut self) -> Result<(), android_c_interface_StatusCode>
fn ping_binder(&mut self) -> Result<(), android_c_interface_StatusCode>
Source§impl<T> IBinderInternal for Twhere
T: AsNative<AIBinder>,
impl<T> IBinderInternal for Twhere
T: AsNative<AIBinder>,
Source§fn prepare_transact(&self) -> Result<Parcel, android_c_interface_StatusCode>
fn prepare_transact(&self) -> Result<Parcel, android_c_interface_StatusCode>
submit_transact
.Source§fn submit_transact(
&self,
code: u32,
data: Parcel,
flags: u32,
) -> Result<Parcel, android_c_interface_StatusCode>
fn submit_transact( &self, code: u32, data: Parcel, flags: u32, ) -> Result<Parcel, android_c_interface_StatusCode>
Source§fn is_binder_alive(&self) -> bool
fn is_binder_alive(&self) -> bool
Source§fn set_requesting_sid(&mut self, enable: bool)
fn set_requesting_sid(&mut self, enable: bool)
Source§fn dump<F>(
&mut self,
fp: &F,
args: &[&str],
) -> Result<(), android_c_interface_StatusCode>where
F: AsRawFd,
fn dump<F>(
&mut self,
fp: &F,
args: &[&str],
) -> Result<(), android_c_interface_StatusCode>where
F: AsRawFd,
Source§fn get_extension(
&mut self,
) -> Result<Option<SpIBinder>, android_c_interface_StatusCode>
fn get_extension( &mut self, ) -> Result<Option<SpIBinder>, android_c_interface_StatusCode>
Source§fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<(), StatusCode>>(
&self,
code: TransactionCode,
flags: TransactionFlags,
input_callback: F,
) -> Result<Parcel, StatusCode>
fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<(), StatusCode>>( &self, code: TransactionCode, flags: TransactionFlags, input_callback: F, ) -> Result<Parcel, StatusCode>
prepare_transact
followed by
`submit_transact. Read more