Skip to content

IBinder接口

解析 IBinder 的低层契约,连接 transact、descriptor、死亡通知、扩展对象和本地/远程实现。

基于android-17.0.0_r1
AndroidBinderIBinderNative框架源码阅读

IBinder接口 ​

IBinder 是 libbinder 的低层可远程对象契约。它不规定具体业务方法,而是规定所有本地 BBinder 和远程 BpBinder 都必须提供的能力:事务发送、接口 descriptor、存活探测、dump、死亡通知、扩展对象和对象附加。BnInterface/BpInterface、AIDL Stub/Proxy 都建立在这组契约上。

本文面向已经读过 BBinder本地对象、BpBinder代理对象 和 BnInterface与BpInterface模板 的读者。本文从接口层解释“调用者究竟依赖什么”,不重复实现两个具体子类,也不展开 Binder 驱动内部的 node/ref 数据结构。

1. 契约分层 ​

1.1 核心方法 ​

源码文件:frameworks/native/libs/binder/include/binder/IBinder.h

cpp
class IBinder : public virtual RefBase {
public:
    virtual sp<IInterface> queryLocalInterface(
            const String16& descriptor);
    virtual const String16& getInterfaceDescriptor() const = 0;
    virtual bool isBinderAlive() const = 0;
    virtual status_t pingBinder() = 0;
    virtual status_t dump(int fd,
                          const Vector<String16>& args) = 0;
    virtual status_t transact(uint32_t code,
                              const Parcel& data,
                              Parcel* reply,
                              uint32_t flags = 0) = 0;
};

IBinder 把“如何调用”与“调用什么”分开:transact() 负责低层消息,业务接口在上层定义 code 和 Parcel。descriptor 是对象身份,isBinderAlive() 是最后一次已知状态,不能当作实时探测保证。

1.2 标准code ​

cpp
enum {
    FIRST_CALL_TRANSACTION = 0x00000001,
    PING_TRANSACTION = B_PACK_CHARS('_', 'P', 'N', 'G'),
    DUMP_TRANSACTION = B_PACK_CHARS('_', 'D', 'M', 'P'),
    INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
    EXTENSION_TRANSACTION = B_PACK_CHARS('_', 'E', 'X', 'T'),
    FLAG_ONEWAY = 0x00000001,
    FLAG_CLEAR_BUF = 0x00000020,
};

标准 code 占用低层协议空间;业务 code 从 FIRST_CALL_TRANSACTION 到 LAST_CALL_TRANSACTION 选择。FLAG_ONEWAY 和 FLAG_CLEAR_BUF 是事务 flags,不是业务方法 code。

2. 事务契约 ​

2.1 同步与oneway ​

transact() 接受 code、Parcel、可选 reply 和 flags。同步调用由 IPCThreadState 等待返回;oneway 只提交而不等待业务 reply。接口层只定义 flags 语义,具体读写由 BBinder/BpBinder 和 IPCThreadState 实现。

2.2 Descriptor ​

cpp
virtual const String16& getInterfaceDescriptor() const = 0;

descriptor 用于 queryLocalInterface()、interface_cast() 和 Parcel interface token 校验。它是接口身份,不是服务注册名;ServiceManager 的 "manager" 名称和 IBinder descriptor 处于不同命名空间。

2.3 Dump与ping ​

pingBinder() 是低层存活探测,dump() 以 fd 和参数请求对象输出调试信息;二者都是 IBinder 能力,不要求业务接口额外定义方法。远程实现通常经由 Binder transaction,BBinder 则直接执行本地实现。

3. 死亡契约 ​

3.1 DeathRecipient ​

cpp
class DeathRecipient : public virtual RefBase {
public:
    virtual void binderDied(
            const wp<IBinder>& who) = 0;
};

virtual status_t linkToDeath(
        const sp<DeathRecipient>& recipient,
        void* cookie = nullptr,
        uint32_t flags = 0) = 0;

死亡通知只对远程 Binder 有意义;本地对象 owner 与调用者在同一进程,进程不死本地 Binder 就不会单独死亡。回调接收弱 IBinder,不能在死亡回调中把它强提升为可用对象。

3.2 引用条件 ​

接口文档明确要求调用者持有被监听 Binder 的引用;当所有引用释放时,死亡通知会自动解除。DeathRecipient 本身使用弱引用,调用者也必须持有 recipient 的强引用直到通知不再需要。

3.3 Frozen回调 ​

FrozenStateChangeCallback 观察进程冻结/解冻,但事件可能合并,不能用来统计每一次状态转换。它和死亡通知是两个独立回调契约:一个表示进程冻结状态,一个表示远程 Binder owner 消失。

4. 扩展与对象 ​

4.1 Extension ​

getExtension() 允许在不修改原接口的情况下挂接下游扩展 Binder。调用者先获取扩展 Binder,再通过 interface_cast<IBar>() 转换;没有扩展或类型不匹配时返回空。扩展不是给原接口增加隐式业务方法,而是新增接口对象。

4.2 ObjectManager ​

attachObject()、findObject()、detachObject() 和 lookupOrCreateWeak() 为 Binder 对象附加用户态数据。对象 ID 由调用者所有,ObjectManager 只管理指针、cleanup cookie 和 cleanup 函数;它不改变 Binder 驱动 node,也不创建远程引用。

4.3 本地/远程识别 ​

BBinder::localBinder() 返回本地对象,BpBinder::remoteBinder() 返回远程代理。IBinder 接口统一暴露两种实现,但调用者只能把这些方法作为对象层级判断,不能仅凭 descriptor 推断本地/远程。

5. 实现消费者 ​

5.1 BBinder ​

本地 BBinder::transact() 重置输入 Parcel 位置并调用 onTransact();默认处理 descriptor/dump,子类处理业务 code。BBinder::linkToDeath() 返回 INVALID_OPERATION,因为它没有远程 owner。

5.2 BpBinder ​

远程 BpBinder::transact() 把自身 handle 交给 IPCThreadState;返回 DEAD_OBJECT 后将代理标记为不存活。BpBinder::linkToDeath() 首次调用向驱动请求死亡通知,并由 IPCThreadState 消费后回调 recipient。

5.3 IInterface ​

IInterface::asBinder() 通过虚函数取回实现的 IBinder;interface_cast() 通过 descriptor 查询本地接口或构造远程 Proxy。IBinder 是二者的共同低层边界,不是业务接口本身。

6. 测试边界 ​

6.1 基础对象 ​

源码文件:frameworks/native/libs/binder/tests/binderLibTest.cpp

PromoteLocal 验证本地 IBinder 的强弱引用;WasParceled 验证 Binder 写入 Parcel 后状态变化;AddManagerToManager 将 IServiceManager 转回 IBinder 并再次注册,覆盖 IInterface::asBinder() 到 IBinder 契约的连接。

6.2 远程能力 ​

DeathNotificationStrongRef、FrozenStateChangeNotification 和普通 NOP transaction 测试分别覆盖死亡、冻结回调和事务能力。测试证明具体能力的返回/通知边界,不把 isBinderAlive() 当作完整健康检查。

6.3 可执行阅读 ​

bash
rg -n "class IBinder|FIRST_CALL_TRANSACTION|FLAG_ONEWAY|linkToDeath|FrozenStateChangeCallback" \
  frameworks/native/libs/binder/include/binder/IBinder.h

rg -n "localBinder|remoteBinder|BBinder::transact|BpBinder::transact" \
  frameworks/native/libs/binder/Binder.cpp \
  frameworks/native/libs/binder/BpBinder.cpp

rg -n "PromoteLocal|WasParceled|DeathNotificationStrongRef|FrozenStateChangeNotification" \
  frameworks/native/libs/binder/tests/binderLibTest.cpp

排查 Binder 能力异常时,先明确失败的是事务、descriptor、ping/dump、死亡通知、冻结回调还是 extension;这些都由 IBinder 提供,但 owner、返回码和生效时机不同,不能用一个“Binder 不可用”结论覆盖。