您的位置:首页 > 其它

binder 回顾

2016-05-23 15:21 316 查看

一直都在忙碌,趁着闲暇之余,将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

随笔记录一下,有不对之处敬请提出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  binder servicemanag