這篇筆記粗略的介紹下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;
}
}