Native空間binder核心類

這篇筆記粗略的介紹下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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章