ServiceManager启动于单独的进程,要早于zygote启动,启动时首先运行到service_manager.c的main函数,对binder进行初始化并进入binderloop
int main(int argc, char **argv){
bs = binder_open(128*1024);
binder_become_context_manager(bs);
binder_loop(bs, svcmgr_handler);
}
binder_open函数定义在binder.c中,打开了binder驱动并进行内存映射
bs->fd = open("/dev/binder", O_RDWR);
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
binder_become_context_manager同样定义在binder.c中,是向驱动注册0号节点成为manager
ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
binder_loop也是定义在binder.c中,是一个死循环,通过ioctl监听binder调用,如果有消息,进行解析
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
binder_loop中传入的svcmgr_handler是一个函数指针(回调),经过一层一层传递,传递到binder_parse最后一个参数func,在binder_parse中,根据binder命令对func进行回调
int binder_parse(struct binder_state *bs, struct binder_io *bio,uintptr_t ptr, size_t size, binder_handler func){
switch(cmd){
case BR_TRANSACTION:
res = func(bs, txn, &msg, &reply);
binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
break;
}
}
svcmgr_handler在service_manager.c中,根据不同的命令码对查找或添加服务进行操作
int svcmgr_handler(struct binder_state *bs,struct binder_transaction_data *txn,struct binder_io *msg,struct binder_io *reply){
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
// 拿到服务名字
s = bio_get_string16(msg, &len);
// 查找拿到节点
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
// 通过binder回复结果
bio_put_ref(reply, handle);
break;
case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
// 添加service
do_add_service(bs, s, len, handle, txn->sender_euid,allow_isolated, txn->sender_pid);
break;
case SVC_MGR_LIST_SERVICES:
// 遍历
svc_can_list(txn->sender_pid)
// 打印
bio_put_string16(reply, si->name);
break;
}
do_find_service函数内部调用find_svc对svclist进行遍历,找到名字相同的进行返回
for (si = svclist; si; si = si->next) {
if ((len == si->len) &&
!memcmp(s16, si->name, len * sizeof(uint16_t))) {
return si;
}
}
do_add_service同样调用find_svc对svclist进行遍历,如果没有找到,就添加一个节点
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
// 经过一系列参数设置,添加进来
si->next = svclist;
svclist = si;
C层次的ServiceManager大概流程就是这样,接下来看java层的ServiceManager,这个类主要是getService方法
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
如果缓存中有要查询的binder,就直接返回,否则就调用native的servicemanager进行查询,这里是用binder进行查询的,首先获得ServiceManager的binder,在调用Service_manager.c的方法进行查询,添加