ServiceManager
基于 Android 9.0 源码。
ServiceManager是Binder IPC通信过程中的守护进程,本身也是一个Binder服务,但并没有采用libbinder中的多线程模型来与Binder驱动通信,
而是自行编写了binder.c直接和Binder驱动来通信,并且只有一个循环binder_loop来进行读取和处理事务,这样的好处是简单而高效。
ServiceManager本身工作相对简单,其功能:查询和注册服务。 对于Binder IPC通信过程中,
其实更多的情形是BpBinder和BBinder之间的通信,比如ActivityManagerProxy和ActivityManagerService之间的通信等
涉及文件
./frameworks/native/cmds/servicemanager/binder.h
./frameworks/native/cmds/servicemanager/binder.c
./frameworks/native/cmds/servicemanager/service_manager.c
./frameworks/native/cmds/servicemanager/vndservicemanager.rc
./frameworks/native/cmds/servicemanager/servicemanager.rc
启动过程
通过 servicemanager.rc 启动 servicemanager 进程。
打开binder驱动,注册成为binder管理者,进入无线循环,读取处理client发来的请求
binder_open:
1. 打开binder驱动
2. 判断当前内核binder驱动版本和用户版本一致
3. 将一段内存从进程空间映射到内核空间
binder_become_context_manager:
1. 注册当前进程为binder服务管家
binder_loop:
1. 循环从binder驱动读取IPC数据处理
关键数据结构
struct binder_io;
struct svcinfo;
struct binder_death; // 存储death处理函数,和相应的 svcinfo
struct svcinfo * svclist; // 全局变量注册的service info列表
关键代码调用流程
main ==> binder_open
==> binder_become_context_manager
==> binder_loop(svcmgr_handler)
binder_open ==> fd = open("/dev/binder") ==> ioctl(fd, BINDER_VERSION, &vers) ==> mmap()
binder_become_context_manager ==> ioctl(fd, BINDER_SET_CONTEXT_MGR, 0)
binder_loop ==> binder_write(BC_ENTER_LOOPER)
==> for(;;)
==> ioctl(fd, BINDER_WRITE_READ, &bwr/*binder_write_read*/) ==> readbuf
==> binder_parse(readbuf, svcmgr_handler)
binder_parse ==> while(has data)
==> cmd ==> BR_TRANSACTION_COMPLETE
==> BR_TRANSACTION ==> ptr/binder_transaction_data txn
==> svcmgr_handler(txn, &msg, &reply)
==> binder_free_buffer / binder_send_reply
==> BR_REPLY ==> ptr/binder_transaction_data txn
==> BR_DEAD_BINDER ==> ptr/binder_death death
==> death->func(death)
binder_free_buffer ==> binder_write(BC_FREE_BUFFER, txn->data.ptr.buffer)
binder_send_reply ==> binder_write(BC_FREE_BUFFER, BC_REPLY)
binder_write ==> ioctl(fd, BINDER_WRITE_READ, &bwr)
svcmgr_handler(txn, msg, reply) ==> 校验合法
==> txn->code ==> SVC_MGR_GET_SERVICE/SVC_MGR_CHECK_SERVICE ==> do_find_service
==> SVC_MGR_ADD_SERVICE ==> do_add_service
==> SVC_MGR_LIST_SERVICES
do_find_service ==> find_svc(name) ==> svcinfo->handle
do_add_service ==> find_svc(name) ==> svcinfo_death/si->next = svclist;svclist = si
==> binder_acquire
==> binder_link_to_death
svcinfo_death ==> binder_release ==> binder_write(BC_RELEASE, svcinfo->handle)
binder_acquire ==> binder_write(BC_ACQUIRE, svcinfo->handle)
binder_link_to_death ==> binder_write(BC_REQUEST_DEATH_NOTIFICATION, handle, binder_death)