注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

民主与科学

独立之人格,自由之思想

 
 
 

日志

 
 

Binder库简介  

2012-05-07 08:07:12|  分类: 深入研究 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
本文编辑整理自:http://linux.chinaunix.net/techdoc/net/2009/05/05/1110014.shtml
一、概述
android的binder,一半功劳属于binder驱动(common/drivers/staging/android/binder.c),而另一半功劳则属于c++的binder库(framework/base/libs/binder),binder库所有的文件作为Android的uitls库的一部分,这个库编译后的名称为libutils.so,是Android系统中的一个公共库
主要文件的路径如下所示:
frameworks/base/include/utils/* 
frameworks/base/libs/utils/*
主要的头文件有:
RefBase.h :  引用计数,定义类RefBase。
Parcel.h : 为在IPC中传输的数据定义容器,定义类Parcel
IBinder.h: Binder对象的抽象接口, 定义类IBinder
Binder.h:Binder对象的基本功能, 定义类Binder和BpRefBase
BpBinder.h:BpBinder的功能,定义类BpBinder
IInterface.h:为抽象经过Binder的接口定义通用类,定义类IInterface,类模板BnInterface,类模板BpInterface
ProcessState.h: 表示进程状态的类,定义类ProcessState。关于此的详细内容请参考《Binder机制之ProcessState
IPCThreadState.h:表示IPC线程的状态,定义类IPCThreadState
各个类之间的关系如下所示:
图1
binder库简介 - hubingforever - 民主与科学
 
IInterface.h中定义的BnInterfaceBpInterface是两个重要的模版,这是为各种程序中使用的。
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();
};

 BpInterface模版的定义如下所示:

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
                                BpInterface(const sp<IBinder>& remote);

protected:
    virtual IBinder*            onAsBinder();
};

这两个模版在使用的时候,起到得作用实际上都是双继承:使用者定义一个接口INTERFACE,然后使用BnInterfaceBpInterface两个模版结合自己的接口,构建自己的BnXXXBpXXX两个类。
DECLARE_META_INTERFACEIMPLEMENT_META_INTERFACE两个宏用于帮助接口类INTERFACE(比如 IServiceManager的实现,她们的都在IInterface.h

#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const android::String16 descriptor;                          \
    static android::sp<I##INTERFACE> asInterface(                       \
            const android::sp<android::IBinder>& obj);                  \
    virtual const android::String16& getInterfaceDescriptor() const;    \
    I##INTERFACE();                                                     \
    virtual ~I##INTERFACE();                                            \


#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const android::String16 I##INTERFACE::descriptor(NAME);             \
    const android::String16&                                            \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
            const android::sp<android::IBinder>& obj)                   \
    {                                                                   \
        android::sp<I##INTERFACE> intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \

二、Binder的运作简介
2.1 Binder的工作机制简介
      Service Manager是一个守护进程,它负责启动各个进程之间的服务,对于相关的两个需要通讯的进程,它们通过调用libutil.so库实现通讯,而真正通讯的机制,是内核空间中的一块共享内存。
关于Service Manager的详细内容请参考《Android系统Binder机制之一(Service Manager篇)
图2
binder库简介 - hubingforever - 民主与科学
 
2.2、从应用程序的角度看Binder
从应用程序的角度看Binder一共有三个方面:
服务端:例如BnABC,这是一个需要被继承和实现的类。
客户端的Proxy代理:例如BpABC,这是一个在接口框架中被实现,但是在接口中没有体现的类。
客户端:例如客户端得到一个接口ABC,在调用的时候实际上被调用的是BpABC
图3
binder库简介 - hubingforever - 民主与科学
服务端功能(Bn)部分做的:
    实现BnABC:: BnTransact() 
    注册服务:IServiceManager::AddService
客服端代理部分(Bp)做的:
    实现几个功能函数,调用BpABC::remote()->transact()
客户端做的:
    获得ABC接口,然后调用接口(实际上调用了BpABC,继而通过IPC调用了BnABC,然后调用了具体的功能)
       在程序的实现过程中BnABC和BpABC是双继承了接口ABC。一般来说BpABC是一个实现类,这个实现类不需要在接口中体现,它实际上负责的只是通讯功能,不执行具体的功能;BnABC则是一个接口类,需要一个真正工作的类来继承、实现它,这个类才是真正执行具体功能的类。
       在客户端中,从ISeriviceManager中获得一个ABC的接口,客户端调用这个接口,实际上是在调用BpABC,而BpABC又通过Binder的IPC机制和BnABC通讯,BnABC的实现类在后面执行。
  事实上,服务器的具体实现和客户端是两个不同的进程,如果不考虑进程间通讯的过程,从调用者的角度,似乎客户端在直接调用另外一个进程间的函数——当然这个函数必须是接口ABC中定义的
三、一个Binder的实现实例
3.1 一个利用接口的具体实现
    PermissionController也是libutils中定义的一个有关权限控制的接口,它一共包含两个文件:IPermissionController.hIPermissionController.cpp这个结构在所有类的实现中都是类似的。
     头文件IPermissionController.h的主要内容是定义IPermissionController接口和类BnPermissionController

class IPermissionController : public IInterface
{
public:
    DECLARE_META_INTERFACE(PermissionController);

    virtual bool                checkPermission(const String16& permission,
                                                int32_t pid, int32_t uid) = 0;
    
    enum {
        CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION
    };
};
IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
// ----------------------------------------------------------------------

class BnPermissionController : public BnInterface<IPermissionController>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

IPermissionController是一个接口类,只有checkPermission()一个纯虚函数。
BnPermissionController继承了以BnPermissionController实例化模版类BnInterface。因此,BnPermissionController,事实上BnPermissionController双继承了BBinder和IPermissionController。
 实现文件IPermissionController.cpp中,首先实现了一个BpPermissionController。

class BpPermissionController : public BpInterface<IPermissionController>
{
public:
    BpPermissionController(const sp<IBinder>& impl)
        : BpInterface<IPermissionController>(impl)
    {
    }

    virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
        data.writeString16(permission);
        data.writeInt32(pid);
        data.writeInt32(uid);
        remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
        // fail on exception
        if (reply.readExceptionCode() != 0) return 0;
        return reply.readInt32() != 0;
    }
};

BpPermissionController继承了BpInterface<IPermissionController>,它本身是一个已经实现的类,而且并没有在接口中体现。这个类按照格式写就可以,在实现checkPermission()函数的过程中,使用Parcel作为传输数据
的容器,传输中时候transact()函数,其参数需要包含枚举值CHECK_PERMISSION_TRANSACTION
    BnPermissionController中实现的onTransact()函数如下所示

status_t BnPermissionController::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    //printf("PermissionController received: "); data.print();
    switch(code) {
        case CHECK_PERMISSION_TRANSACTION: {
            CHECK_INTERFACE(IPermissionController, data, reply);
            String16 permission = data.readString16();
            int32_t pid = data.readInt32();
            int32_t uid = data.readInt32();
            bool res = checkPermission(permission, pid, uid);
            reply->writeNoException();
            reply->writeInt32(res ? 1 : 0);
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

在onTransact()函数中根据枚举值判断数据使用的方式。注意,由于BnPermissionController也是继承了类
IPermissionController,但是纯虚函数checkPermission()依然没有实现。因此这个
BnPermissionController类并不能实例化,它其实也还是一个接口,需要一个实现类来继承它,那才是实现具体功能的类。
 3.2 BnABC的实现
    本地服务启动后将形成一个守护进程,具体的本地服务是由一个实现类继承BnABC来实现的,这个服务的名称通常叫做ABC。
    在其中,通常包含了一个instantiate()函数,这个函数一般按照如下的方式实现:
void ABC::instantiate() {
    defaultServiceManager()->addService(
            String16("XXX.ABC"), new ABC ());
}
    按照这种方式,通过调用defaultServiceManager()函数,将增加一个名为"XXX.ABC"的服务。
    在这个defaultServiceManager()函数中调用了:
ProcessState::self()->getContextObject(NULL));
    IPCThreadState* ipc = IPCThreadState::self();
   IPCThreadState::talkWithDriver()
在ProcessState 类建立的过程中调用open_driver()打开驱动程序,在talkWithDriver()的执行过程中。
3.3 BpABC调用的实现
    BpABC调用的过程主要通过mRemote()->transact() 来传输数据,mRemote()是BpRefBase的成员,它是一个IBinder。这个调用过程如下所示:
    mRemote()->transact() 
    Process::self() 
    IPCThreadState::self()->transact()
    writeTransactionData()
    waitForResponse()
    talkWithDriver()
    ioctl(fd, BINDER_WRITE_READ, &bwr)
    在IPCThreadState::executeCommand()函数中,实现传输操作。
四、Binder的实现实例(CameraService)
CameraService也是Binder的一个实现实例,其结构图如下
图4
Binder库简介 - hubingforever - 民主与科学
 
结束!
  评论这张
 
阅读(980)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017