安卓源码解析:Binder进程间通讯机制(4)-内核空间Binder驱动详解(Binder驱动库 C/C++接口简介)

目录

  1. Binder进程间通讯机制(1)-简况
  2. Binder进程间通讯机制(2)-内核空间Binder驱动详解(基础数据结构)
  3. Binder进程间通讯机制(3)-内核空间Binder驱动详解(Binder驱动内存管理)
  4. Binder进程间通讯机制(4)-内核空间Binder驱动详解(Binder驱动库 C/C++接口简介)
  5. Binder进程间通讯机制(5)-从ServiceManager的角度分析IPC原理

Binder由Service组件和Client组件组成,两个组件通过Binder内核进行通信,Service组件继承BnInterface,包含BnXXXX开头的所有类,Service组件被称为本地对象对应Binder驱动实体对象,Client组件被称为代理对象对应BInder驱动中的引用对象.中的最终功能的实现是继承了BnXXXX的Service类,数据通过IPCThreadState和ProcessState进行向Binder内核通讯.

Service的结构图如下:

这里写图片描述

  • BnInterface继承IXXXX以及BBinder
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;

protected:
    virtual IBinder*            onAsBinder();
};

INTERFACE 为进程自定义的Service组件接口,Client和Service组件都会继承这个接口,并实现里面的方法.Service组件具体的实现会定义在XXXX类中.Service端除了要实现接口还需要实现一个Binder本地对象BnXXXX.

  • 具体实现类XXXX

比如BServiceManager,里面定义了从ServiceManger中获取Service组件getService,以及Client组件向Service组件注册组件setService的具体实现.

status_t BServiceManager::addService(const String16& name, const sp<IBinder>& service)
{
    AutoMutex _l(mLock);
    LOGI("ServiceManager: addService(%s, %p)\n", String8(name).string(), service.get());
    const ssize_t res = mServices.add(name, service);
    if (res >= NO_ERROR) {
        mChanged.broadcast();
        return NO_ERROR;
    }
    return res;
}
sp<IBinder> BServiceManager::getService(const String16& name) const
{
    AutoMutex _l(mLock);
    ssize_t i = mServices.indexOfKey(name);
    LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
    if (i >= 0) return mServices.valueAt(i);
    return NULL;
}
  • BnXXXX

例如 ServiceManager组件的本地对象BnServiceManager用来定义onTransct方法接收binder传递的指令判断后分发给实现类ServiceManager的两个方法.

status_t BnServiceManager::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case ADD_SERVICE_TRANSACTION: {
            //添加Service
            CHECK_INTERFACE(IServiceManager, data, reply);
            String16 which = data.readString16();
            sp<IBinder> b = data.readStrongBinder();
            status_t err = addService(which, b);
            reply->writeInt32(err);
            return NO_ERROR;
        } break;
    }
}
};

//虚函数addService 被BServiceManager实现
virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
    ....
} 

BServiceManager的addService

status_t BServiceManager::addService(const String16& name, const sp<IBinder>& service)
{
    AutoMutex _l(mLock);
    LOGI("ServiceManager: addService(%s, %p)\n", String8(name).string(), service.get());
    //将Service组件注册到mService集合中
    const ssize_t res = mServices.add(name, service);
    if (res >= NO_ERROR) {
        mChanged.broadcast();
        return NO_ERROR;
    }
    return res;
}
  • BBinder

BnInterface继承了BBinder,在Service组件中,BBinder定义重要的函数onTransact,当Binder代理对象通过Binder驱动程序向一个Binder本地对象发送一个进程间通讯请求时,Binder驱动会调用transact方法进行请求,调用onTransact方法分发与业务相关的请求.其实onTransact会被BBinder的子类,例如BnServiceManager 进行实现,会调用上面所说的BnServiceManageronTransact方法.

  • BnInterface

template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;

protected:
    virtual IBinder*            onAsBinder();
};


inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
        const String16& _descriptor)
{
    if (_descriptor == INTERFACE::descriptor) return this;
    return NULL;
}

BnInterface主要提供queryLocalInterfacegetInterfaceDescriptor,第一个方法主要用来获取BnBinder本地对象,第二个方法用来获取描述这个本地对象的字符串.

  • IPCThreadState
class IPCThreadState
{
public:
    static  IPCThreadState*     self();

            status_t            transact(int32_t handle,
                                         uint32_t code, const Parcel& data,
                                         Parcel* reply, uint32_t flags);

private:
    const   sp<ProcessState>    mProcess;
};

}; // namespace android

IPCThreadState是用来和Binder程序进程交互的,每一个Binder线程内部都有一个IPCThreadState,可以根据函数self()获取这个对象,transact是用来和Binder进程交互的函数,与Binder进程交互又是通过调用私有函数talkWithDriver实现,他一方面负责发送给Binder驱动数据一方面用来接收Binder驱动发送过来的数据.

  • ProcessState

每个BInder线程对应的IPCThreadState内部都有一个mProcess成员变量对应的ProcessState对象,他负责初始化Binder设备,负责打开设备文件/dev/binder,并将它映射到进程的地址空间,让每一个BInder线程和Binder驱动建立连接.

扫描二维码关注公众号,回复: 2908148 查看本文章

Client的结构图如下:

这里写图片描述

  • BpXXXX

BpXXXX为Binder代理对象的具体实现类,与Binder本地对象继承同一个`IInterface,实现同样的接口,例如在BpServiceManager`中实现了getService以及addService虚函数,当有其他进程要调用ServiceManager的时候会先获取到SM的Binder代理对象并调用他的具体方法.

//代理對象addService
    virtual status_t addService(const String16& name, const sp<IBinder>& service)
    {
        Parcel data, reply;
        //写入协议头(请求头)
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        //将要传递的Service组件封装成binder结构体
        data.writeStrongBinder(service);
        //调用BpBinder 的 transact方法
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }
  • BpRefBase

BpRefBase用来为Binder代理对象提供进程间通讯的抽象接口,其中成员变量mRemote指向一个BpBinder对象,可以通过方法remote()获取.

class BpRefBase : public virtual RefBase
{
protected:
    inline  IBinder*        remote()                { return mRemote; }
    inline  IBinder*        remote() const          { return mRemote; }

private:
    IBinder* const          mRemote;
};

}; // namespace android
  • BpBinder

BpBinder为Binder代理对象实现的进程间通讯接口,成员变量mHandle是一个表示Client组件的句柄,每一个Client组件在Binder驱动中都对应一个Binder引用对象,每一个Binder引用对象都有一个句柄值,client组件就是通过这个句柄值来和binder驱动中的binder引用对象建立联系.

BpBinder的transact方法用来向service组件发送进程间通讯请求,client端会通过这个方法将句柄值发送给Binder驱动,这样binder驱动就能跟着这个句柄找到binder引用对象,继而找到binder实体对象,并将请求发送给binder实体对象所对应的service组件.

而BpBinder具体如何发送指令又是通过IPCThreadState处理的.

猜你喜欢

转载自blog.csdn.net/hfyd_/article/details/81985848
今日推荐