#binder #interface #service #android #parcel #object #transaction

android-binder

Safe bindings to Android Binder, restricted to the NDK

2 releases

new 0.1.1 Dec 19, 2024
0.1.0 Oct 24, 2024

#695 in Development tools

Apache-2.0

305KB
4.5K SLoC

Safe Rust interface to Android libbinder.

This crate is primarily designed as an target for a Rust AIDL compiler backend, and should generally not be used directly by users. It is built on top of the binder NDK library to be usable by APEX modules, and therefore only exposes functionality available in the NDK interface.

Example

The following example illustrates how the AIDL backend will use this crate.

use binder::{
    declare_binder_interface, Binder, IBinder, Interface, Remotable, Parcel, SpIBinder,
    StatusCode, TransactionCode,
};

// Generated by AIDL compiler
pub trait ITest: Interface {
    fn test(&self) -> binder::Result<String>;
}

// Creates a new local (native) service object, BnTest, and a remote proxy
// object, BpTest, that are the typed interfaces for their respective ends
// of the binder transaction. Generated by AIDL compiler.
declare_binder_interface! {
    ITest["android.os.ITest"] {
        native: BnTest(on_transact),
        proxy: BpTest,
    }
}

// Generated by AIDL compiler
fn on_transact(
    service: &dyn ITest,
    code: TransactionCode,
    _data: &BorrowedParcel,
    reply: &mut BorrowedParcel,
) -> binder::Result<()> {
    match code {
        SpIBinder::FIRST_CALL_TRANSACTION => {
            reply.write(&service.test()?)?;
            Ok(())
        }
        _ => Err(StatusCode::UNKNOWN_TRANSACTION),
    }
}

// Generated by AIDL compiler
impl ITest for Binder<BnTest> {
    fn test(&self) -> binder::Result<String> {
        self.0.test()
    }
}

// Generated by AIDL compiler
impl ITest for BpTest {
    fn test(&self) -> binder::Result<String> {
       let reply = self
           .as_binder()
           .transact(SpIBinder::FIRST_CALL_TRANSACTION, 0, |_| Ok(()))?;
       reply.read()
    }
}

// User implemented:

// Local implementation of the ITest remotable interface.
struct TestService;

impl Interface for TestService {}

impl ITest for TestService {
    fn test(&self) -> binder::Result<String> {
       Ok("testing service".to_string())
    }
}

Dependencies

~0–2MB
~39K SLoC