免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1444 | 回复: 0
打印 上一主题 下一主题

Android的IPC机制Binder的各个部分 3 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-02 21:57 |只看该作者 |倒序浏览

3.1 一个利用接口的具体实现
    PermissionController也是libutils中定义的一个有关权限控制的接口,它一共包含两个文件:IPermissionController.h和IPermissionController.cpp这个结构在所有类的实现中都是类似的。
     头文件IPermissionController.h的主要内容是定义IPermissionController接口和类BnPermissionController:
[color="#008000"]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
    };
};
class BnPermissionController : public BnInterface
{
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。
[color="#008000"]class BpPermissionController : public BpInterface
{
public:
    BpPermissionController(const sp& impl)
        : BpInterface(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);
        if (reply.readInt32() != 0) return 0;
        return reply.readInt32() != 0;
    }
};
IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");



BpPermissionController继承了BpInterface,它本身是一个
已经实现的类,而且并没有在接口中体现。这个类按照格式写就可以,在实现checkPermission()函数的过程中,使用Parcel作为传输数据
的容器,传输中时候transact()函数,其参数需要包含枚举值CHECK_PERMISSION_TRANSACTION。
IMPLEMENT_META_INTERFACE用于扶助生成。
    BnPermissionController中实现的onTransact()函数如下所示:
[color="#008000"]status_t BnPermissionController:: BnTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    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->writeInt32(0);
            reply->writeInt32(res ? 1 : 0);
            return NO_ERROR;
        } break;
        default:
            return BBinder:: BnTransact(code, data, reply, flags);
    }
}

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

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/66024/showart_1889076.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP