Service Manager是所有服务的管理器,因此,所有Server(System Server)都要向它注册,应用程序则向Service Manager查询相应的服务。其实现位于"frameworks/base/cmds/servicemanager\service_manager.c"文件中。
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; }
struct binder_state *binder_open(unsigned mapsize) { struct binder_state *bs; bs = malloc(sizeof(*bs)); if (!bs) { errno = ENOMEM; return 0; } bs->fd = open("/dev/binder", O_RDWR); if (bs->fd < 0) { fprintf(stderr,"binder: cannot open device (%s)\n", strerror(errno)); goto fail_open; } bs->mapsize = mapsize; bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); if (bs->mapped == MAP_FAILED) { fprintf(stderr,"binder: cannot map device (%s)\n", strerror(errno)); goto fail_map; } /* TODO: check version */ return bs; fail_map: close(bs->fd); fail_open: free(bs); return 0; }
然后调用binder_become_context_manager使得它称为context manager,也就是Service manager,这个特殊的服务用来管理其他的所有服务。
int binder_become_context_manager(struct binder_state *bs) { return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); }
Service Manager通过ioctl BINDER_SET_CONTEXT_MGR向Binder驱动声明自己是服务管理器,作为服务管理器有两个最重要的工作,接收其他server的服务注册; 为客户端提供查询和获取服务。因此Service最后会进入一个监听循环,等待用户的请求,并使用srcmgr_handler回调函数处理用户请求。
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); if (res < 0) { LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno)); break; } res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func); if (res == 0) { LOGE("binder_loop: unexpected reply?!\n"); break; } if (res < 0) { LOGE("binder_loop: io error %d %s\n", res, strerror(errno)); break; } } }
binder_parse分析@readbuf中的请求,bwr.read_consumed是请求的长度,@func是请求处理函数
ServiceManager数据结构
90 struct svcinfo 91 { 92 struct svcinfo *next; 93 void *ptr; 94 struct binder_death death; 95 unsigned len; 96 uint16_t name[0]; 97 };
@next,所有的service通过next链接到全局变量svclist
@ptr,虽然从命名上是一个pointer,但是存储的是一个handle,一般来说从0x01开始,0x00保留给service manager自身。
@len,name的长度
@name,是service名字,client端要通过这个名字找到匹配的服务。
struct binder_io { char *data; /* pointer to read/write from */ uint32_t *offs; /* array of offsets */ uint32_t data_avail; /* bytes available in data buffer */ uint32_t offs_avail; /* entries available in offsets array */ char *data0; /* start of data buffer */ uint32_t *offs0; /* start of offsets buffer */ uint32_t flags; uint32_t unused; };
binder_io是用来生成binder message的辅助结构
@data 是当前可用buffer位置,这个地址随着加入数据,而改变
@offs 是当前可用的offset buffer位置,可以用来存放obj相对于@data0的偏移地址,4bytes
@data_avail 当前可用的data空间大小
@offs_avail 当前空用的offsets大小
@data0 data buffer的起始位置,data0记录着binder_io数据buffer的起始位置
@offs0 offset buffer的起始位置,offs0记录着binder_io offset buffer的起始位置
从@data0 ~ @data保存着对象,@offs0 ~ @offs保存着obj的偏移位置,这个偏移位置是obj地址相对于@data0的偏移位置