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
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
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
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
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 可执行阅读
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 不可用”结论覆盖。
