5 releases

0.2.0 Aug 10, 2023
0.1.4 Aug 10, 2023
0.1.3 Aug 10, 2023
0.1.2 Aug 10, 2023
0.1.1 Aug 10, 2023

#1174 in Development tools

Download history 7/week @ 2023-12-24 2/week @ 2023-12-31 8/week @ 2024-01-07 1/week @ 2024-01-14 22/week @ 2024-02-11 38/week @ 2024-02-18 39/week @ 2024-02-25 18/week @ 2024-03-03 26/week @ 2024-03-10 25/week @ 2024-03-17 2/week @ 2024-03-24 28/week @ 2024-03-31 3/week @ 2024-04-07

63 downloads per month
Used in binder_tokio

Apache-2.0

265KB
3.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
~38K SLoC