Android camera系统开发之IPC (二)

一      系统服务管理器启动

 

 

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

 

你可能感兴趣的:(Android camera系统开发之IPC (二))