以下几篇文章是较深入分析binder机制。
目录
1. Android - Binder机制 - ServiceManager
2. Android - Binder机制 - 普通service注册
3. Android - Binder机制 - 获得普通service
4. Android - Binder机制 - client和普通service交互
5. Android - Binder机制 - Binder框架总结
6. Android - Binder机制 - ProcessState和IPCThreadState
7. Android - Binder机制 - 驱动
Android - Binder机制 - ServiceManager
代码路径:frameworks/base/cmds/servicemanager/service_manager.c
虽然service_manager并不是用类来写的,但是为了好看,还是用类图来表示。
ServiceManager主要有两大功能,一个是监听其他service的addservice请求,一个是监听client的getservice服务。下面分析ServiceManager主要代码和工作。
int main(int argc, char **argv) { struct binder_state *bs; void *svcmgr = BINDER_SERVICE_MANAGER; bs = binder_open(128*1024); if (binder_become_context_manager(bs)) { LOGE("cannot become context manager (%s)\n", strerror(errno)); return -1; } svcmgr_handle = svcmgr; binder_loop(bs, svcmgr_handler); return 0; }ServiceManager以一个独立的进程存在,以上代码主要完成三步工作:
1. binder_open打开binder设备;
2. binder_become_context_manager通过ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0)设置为ServiceManager服务,该服务的handle索引值为0;
3. binder_loop进行循环监听;
binder_loop是最重要的部分,代码就不贴了,binder_loop每次循环都进行如下几步:
1. 通过ioctl(bs->fd, BINDER_WRITE_READ, &bwr)读取binder驱动数据(请求数据);
2. binder_parse解析数据,数据包的第4至7字节是该数据包的类型,常用的包括BR_TRANSACTION(请求转发)和BR_DEAD_BINDER(服务死亡),解析完数据,然后调用相应的处理;
3. 如BR_TRANSACTION请求,通过调用ServiceManager注册的svcmgr_handler回调函数,来处理具体的请求,这些请求包括(SVC_MGR_GET_SERVICE、SVC_MGR_CHECK_SERVICE、SVC_MGR_ADD_SERVICE、SVC_MGR_LIST_SERVICES);
ServiceManager的主要任务就是监听AddService和GetService请求,以下是对这两个请求的具体分析。
svcmgr_handler调用do_add_service函数进行具体处理:
1. svc_can_register判断是否能够注册该服务,有一个allowed数组,定义了可以注册的服务,如果这个服务是自定义的,要在allowed数组添加上这个服务的名称;
2. find_svc检测这个服务是否已经注册过了,如果注册过了,就返回错误;
3. 创建一个新的svcinfo节点,然后将节点添加到svclist中,到此为止,服务只是在ServiceManager进程中注册了,还没有向binder驱动中注册;
4. binder_acquire通过BC_ACQUIRE指令将服务注册到binder中;
5. binder_link_to_death待研究。。。
经过简单的几步,服务就注册到binder了,如果要研究很详细的机制,必须研究binder驱动,binder驱动会在以后篇章深入分析,在此就不做说明了。
当一个client要获得某个服务时,要通过GetService请求获得某个服务,svcmgr_handler调用do_find_service函数进行具体处理:
1. do_find_service只是到svclist查找,如果找不到,就返回NULL,如果找到了就返回svcinfo.ptr;
2. svcinfo的ptr是void *,是一个地址,具体里面放的什么东西,看来还得需要分析驱动,所以我们看到binder真正的机制其实是在驱动里面实现的;
很简单,没有和binder驱动打交道就获得了服务,只是这个ptr确实需要研究明白;
struct svcinfo { struct svcinfo *next; void *ptr; struct binder_death death; unsigned len; uint16_t name[0]; };
待研究。。。