一 系统服务管理器启动
参考Android init 详细过程分析 ,我们知道系统在INIT进程中会分析INIT.RC
我们从init.rc中能看到如下代码
@init.rc
…
service servicemanager /system/bin/servicemanager
user system
critical
onrestart restart zygote
onrestart restart media
所以在INIT的时候会启动servicemanager服务。
@service_manager.c
int svcmgr_handler(struct binder_state *bs,
struct binder_txn *txn,
struct binder_io *msg,
struct binder_io *reply)
{
…
s = bio_get_string16(msg, &len);
if ((len != (sizeof(svcmgr_id) / 2)) ||
memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
fprintf(stderr,"invalid id %s/n", str8(s));
return -1;
}
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
ptr = do_find_service(bs, s, len);
bio_put_ref(reply, ptr);
return 0;
case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
ptr = bio_get_ref(msg);
if (do_add_service(bs, s, len, ptr, txn->sender_euid))
return -1;
break;
…
}
bio_put_uint32(reply, 0);
return 0;
}
我们在以后会看到这几个被标红的case 。
总结一下:
系统在init进程中会分析init.rc,并启动servicemanager服务。
这个服务管理器首先打开binder driver.并告诉binder driver,这是个服务管理进程,然后servicemanager将通过ioctl(bs->fd, BINDER_WRITE_READ, &bwr)读取binder driver的数据,如果没有数据读,将会挂起,一旦有数据出现,系统将通过binder_parse()来分析数据包,并调用svcmgr_handler()来处理分析后的内容,处理结束后再循环去等待binder driver中可读数据。一旦其他进程有对这个服务的请求需要,binder driver就会有数据可读。后续将看到Camera Service如何请求加入.Camera app如何请求获取Camera Service的Binder号
参考service_manager.c文件下的Android.mk
@frameworks/base/cmds/servicemanager/Android.mk
…
LOCAL_SRC_FILES := service_manager.c binder.c
LOCAL_MODULE := servicemanager
这两个文件service_manager.c binder.c会编译为名成为servicemanager应用程序。
而其入口函数是main()
@service_manager.c
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER; //=0 其BINDER_SERVICE_MANAGER定义是0
bs = binder_open(128*1024);
binder_become_context_manager(bs);
svcmgr_handle = svcmgr; //0 存这个句柄
binder_loop(bs, svcmgr_handler);
return 0;
}
1 看到这行bs = binder_open(128*1024);
@frameworks/base/cmds/servicemanager/binder.c
struct binder_state *binder_open(unsigned mapsize)
{
struct binder_state *bs;
bs = malloc(sizeof(*bs));
bs->fd = open("/dev/binder", O_RDWR);
bs->mapsize = mapsize;
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
return bs;
}
用来打开binder的驱动
2 再看到这行binder_become_context_manager(bs);
@frameworks/base/cmds/servicemanager/binder.c
int binder_become_context_manager(struct binder_state *bs)
{
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
通过binder_become_context_manager函数调用来告诉Binder Driver这是一个服务管理进程
3 最后看到这行binder_loop(bs, svcmgr_handler);
@frameworks/base/cmds/servicemanager/binder.c
void binder_loop(struct binder_state *bs, binder_handler func)
{
int res;
struct binder_write_read bwr;
unsigned readbuf[32];
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;
readbuf[0] = BC_ENTER_LOOPER;
binder_write(bs, readbuf, sizeof(unsigned));
for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (unsigned) readbuf;
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
…
}
}
}
这是这个servicemanager的主体。
binder_loop这个函数首先向Binder申明进入BC_ENTER_LOOPER状态。
然后循环调用res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);读取Binder中的数据,如果没有数据,这个进程会被Binder Driver挂起,否则有数据将进入binder_parse(bs, 0, readbuf, bwr.read_consumed, func);分析处理。
真正的实质处理函数是通过binder_loop()传进来的svcmgr_handler()