一 系统服务管理器启动

参考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()

更多相关文章

  1. “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
  2. Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
  3. 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
  4. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  5. android中的保存数据方法
  6. Android(安卓)跨进程通信(一)
  7. Android(安卓)adb.exe程序启动不起来处理方法
  8. Android(安卓)USB Host 使用详解(U盘)(三)
  9. android AsyncQueryHandler的分析

随机推荐

  1. Android(安卓)网络权限配置
  2. JS判断终端类型的几种方法
  3. Android之SharedPreferences详解与原理分
  4. android中Touch事件处理
  5. Android生命周期
  6. Androkd开发坏境配置以及常用插件
  7. Android客户端与服务端交互-客户端GET方
  8. 1、搭建android开发环境
  9. android SDK升级连接不上服务器解决方案
  10. android资源合集