这篇笔记粗略的介绍下libbinder中,代理端和服务端相关的核心类以及它们之间的继承关系。
代理端类继承关系如下(IServiceManager和BpServiceManager是具体的代理端需要实现的类):
服务端类继承关系如下(INetd、BnNetd和NetdNativeService是具体的服务端需要实现的类):
IInterface
无论是代理端还是服务端,描述接口的类都会从IInterface派生。IInterface提供了一个有用的接口:asBinder(),通过该接口可以获取IBinder对象,对于代理端,获取的肯定是BpBinder对象,对于服务端,获取到的肯定是BBinder对象。
class IInterface : public virtual RefBase
{
public:
IInterface();
static sp<IBinder> asBinder(const IInterface*);
static sp<IBinder> asBinder(const sp<IInterface>&);
protected:
virtual ~IInterface();
virtual IBinder* onAsBinder() = 0;
};
静态函数asBinder()有两个版本,但是它们调用的都是抽象函数onAsBinder()。IInterface并未实现该接口,留给了子类BnInterface和BpInterface实现。
BnInterface::onAsBinder()
template<typename INTERFACE>
IBinder* BnInterface<INTERFACE>::onAsBinder()
{
return this;
}
因为BnInterface本身就继承自BBinder,所以直接返回this即可。
BpInterface::onAsBinder()
template<typename INTERFACE>
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
return remote();
}
BpInterface返回的是remote()的返回值,remote()方法来自其父类BpRefBase,而BpRefBase::remote()返回的是其封装的BpBinder对象。
BpRefBase
代理端的BpInterface同时也派生自该类,该类提供的一个最终要的功能是为代理端封装了BpBinder对象,即下面的mRemote,该成员在BpRefBase创建时被初始化。
class BpRefBase : public virtual RefBase
{
protected:
explicit BpRefBase(const sp<IBinder>& o);
virtual ~BpRefBase();
...
// 子类可以通过remote()获取BpBinder对象
inline IBinder* remote() { return mRemote; }
inline IBinder* remote() const { return mRemote; }
private:
...
IBinder* const mRemote;
};
BpInterface
从继承关系上看,BpInterface非常重要,它的直接父类是IXXX和BpRefBase。继承自BpRefBase,BpInterface持有了BpBinder对象,可以和binder驱动进行通信;继承自IXXX,由于IXXX由具体的服务端提供,其中定义了服务端能够提供的RPC原型,所以BpInterface也知道了能够支持的接口,所以代理端只要从BpInterface派生,就可以专注于IXXX接口的实现即可。
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
explicit BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
除了继承关系,BpInterface自己唯一需要实现的就是onAsBinder(),前面已经分析了该方法的作用。
IBinder
所有使用Binder协议的类都必须是该类的子类,该类定义了一些和binder协议相关的内容。
核心方法
transact()
virtual status_t transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) = 0;
该抽象方法有子类BpBinder和BBinder独自实现。
BpBinder
BpBinder最重要的作用就是封装了服务端的句柄。
class BpBinder : public IBinder
{
public:
// 通过静态方法create()创建BpBinder对象,入参为服务端的句柄
static BpBinder* create(int32_t handle);
inline int32_t handle() const { return mHandle; }
virtual status_t transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
private:
const int32_t mHandle;
}
BnInterface
服务端的BnInterface和代理端的BpInterface作用是一样的,只是二者对binder协议的封装方式不同而已,BpInterface是通过继承BpRefBase间接的持有BpBinder的引用,而BnInterface则是直接继承自BBinder。
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
...
protected:
virtual IBinder* onAsBinder();
};
onAsBinder()方法的作用前面已经分析过了。
BBinder
服务端的binder协议封装。
核心方法
transact()
BBinder实现了transact(),从下面的实现看,BBinder实现了PING_TRANSACTION操作,其余的操作由抽象函数onTransact()处理。
status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply, flags);
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
onTransact()
BBinder中的onTransact()中实现了一些Binder框架相关的IPC调用,从设计上看,服务端要提供的其它操作时,应该复写该函数,对于非自身提供的code应该调用BBinder::onTransact()。
status_t BBinder::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
{
switch (code) {
case INTERFACE_TRANSACTION:
...
case DUMP_TRANSACTION:
...
case SHELL_COMMAND_TRANSACTION:
...
case SYSPROPS_TRANSACTION:
...
default:
return UNKNOWN_TRANSACTION;
}
}