binder 回顾

来源:互联网 发布:java 健身房管理系统 编辑:程序博客网 时间:2024/05/21 07:06

一直都在忙碌,趁着闲暇之余,将android的灵魂binder 做个记录。

1、android启动第一用户进程init进程,启动过程中,根据init.rc配置,会启动servicemanager进程。如下:

service servicemanager /system/bin/servicemanager
    class core
    user system

servicemanager主要作用就是与binder driver交互,并将service的name和handle保存到struct svcinfo *svclist = NULL;

链表中。直接代码分析,入口函数main

int main(int argc, char **argv)
{
    struct binder_state *bs;
    bs = binder_open(128*1024);    //打开binder 设备节点,并分配128k的内存空间。

    svcmgr_handle = BINDER_SERVICE_MANAGER;      //handle 为0 表示自己在binder中的handle为0.
    binder_loop(bs, svcmgr)    //启动死循环,与binder 通讯

}

binder.c

struct binder_state *binder_open(size_t mapsize)
{

bs->fd = open("/dev/binder", O_RDWR);】

}


void binder_loop(struct binder_state *bs, binder_handler func)
{

    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);   //从binder  driver读取信息
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);//解析,并根据信息内容将结果返回。并利用func回调到service_manager.c

    }

}

service_manager.c, 以addservice 和getservice为力

int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{

 switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);   //利用name查询service对应的handle,以供client使用
        if (!handle)
            break;
        bio_put_ref(reply, handle);
        return 0;

    case SVC_MGR_ADD_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, handle, txn->sender_euid,
            allow_isolated, txn->sender_pid))   //最终会添加到上述提到的svclist 链表( service 的name 和handle),并伴随整个生命周期
            return -1;
        break;

}

java层想要注册service ,首先要在jni调用流程中获取servicemanager的handle,

sp<IServiceManager> sm = defaultServiceManager();  //创建获取bpbinder
    ProcessState::self()->startThreadPool();  //启动循环与binder driver通讯


sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    
    return gDefaultServiceManager;
}

2、 分析ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);  //获取servicemanager 的handle,从而进行操作
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{

b = new BpBinder(handle);

}

    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);   //与binder driver交互,两个parcel对象, mIn,  mOut
        return false;
    }

3. IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)
{

do {
        processPendingDerefs();
        // now get the next command to be processed, waiting if necessary
        result = getAndExecuteCommand();   ////与binder driver交互,两个parcel对象, mIn,  mOut

}while (result != -ECONNREFUSED && result != -EBADF);

}

3\   client 通过binderproxy 也就是bpbinder 的transact,将参数打包成parcel 并传递给binder,最终调用bbbinder的子类的onTransact方法。

其他就是代码的逻辑处理。 

4、以camera为例。ICameraService.cpp

    virtual int32_t getNumberOfCameras()
    {
        Parcel data, reply;
        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
        remote()->transact(BnCameraService::GET_NUMBER_OF_CAMERAS, data, &reply);   其中remote就是bpbinder

        if (readExceptionCode(reply)) return 0;
        return reply.readInt32();
    }

通过binder机制,调用到bbbinder子类

BnCameraService.cpp

status_t BnCameraService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

    switch(code) {
        case GET_NUMBER_OF_CAMERAS: {
            CHECK_INTERFACE(ICameraService, data, reply);
            reply->writeNoException();
            reply->writeInt32(getNumberOfCameras());
            return NO_ERROR;

}

最终调用子类Cameraservice.cpp

随笔记录一下,有不对之处敬请提出




0 0
原创粉丝点击