binder

Macro declare_binder_interface

Source
macro_rules! declare_binder_interface {
    {
        $interface:path[$descriptor:expr] {
            native: $native:ident($on_transact:path),
            proxy: $proxy:ident,
            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
        }
    } => { ... };
    {
        $interface:path[$descriptor:expr] {
            native: $native:ident($on_transact:path),
            proxy: $proxy:ident,
            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
            stability: $stability:expr,
        }
    } => { ... };
    {
        $interface:path[$descriptor:expr] {
            native: $native:ident($on_transact:path),
            proxy: $proxy:ident {
                $($fname:ident: $fty:ty = $finit:expr),*
            },
            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
        }
    } => { ... };
    {
        $interface:path[$descriptor:expr] {
            native: $native:ident($on_transact:path),
            proxy: $proxy:ident {
                $($fname:ident: $fty:ty = $finit:expr),*
            },
            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
            stability: $stability:expr,
        }
    } => { ... };
    {
        $interface:path[$descriptor:expr] {
            @doc[$native_doc:expr]
            native: $native:ident($on_transact:path),

            @doc[$proxy_doc:expr]
            proxy: $proxy:ident {
                $($fname:ident: $fty:ty = $finit:expr),*
            },

            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?

            stability: $stability:expr,
        }
    } => { ... };
}
Expand description

Declare typed interfaces for a binder object.

Given an interface trait and descriptor string, create a native and remote proxy wrapper for this interface. The native service object ($native) implements Remotable and will dispatch to the function $on_transact to handle transactions. The typed proxy object ($proxy) wraps remote binder objects for this interface and can optionally contain additional fields.

Assuming the interface trait is Interface, $on_transact function must have the following type:

fn on_transact(
    service: &dyn Interface,
    code: TransactionCode,
    data: &BorrowedParcel,
    reply: &mut BorrowedParcel,
) -> binder::Result<()>;

§Examples

The following example declares the local service type BnServiceManager and a remote proxy type BpServiceManager (the n and p stand for native and proxy respectively) for the IServiceManager Binder interface. The interfaces will be identified by the descriptor string “android.os.IServiceManager”. The local service will dispatch transactions using the provided function, on_transact.

use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};

pub trait IServiceManager: Interface {
    // remote methods...
}

declare_binder_interface! {
    IServiceManager["android.os.IServiceManager"] {
        native: BnServiceManager(on_transact),
        proxy: BpServiceManager,
    }
}

fn on_transact(
    service: &dyn IServiceManager,
    code: TransactionCode,
    data: &BorrowedParcel,
    reply: &mut BorrowedParcel,
) -> binder::Result<()> {
    // ...
    Ok(())
}

impl IServiceManager for BpServiceManager {
    // parceling/unparceling code for the IServiceManager emitted here
}

impl IServiceManager for Binder<BnServiceManager> {
    // Forward calls to local implementation
}