ServiceManager源码分析

1,529 阅读4分钟

ServiceManager是Android系统的服务大管家,它负责所有实名Server的管理,比如CameraService,WindowManagerService等等,所以它的重要性可想而知,ServiceManager是单独运行在一个系统进程中的,它在Init.rc的定义如下:

service servicemanager /system/bin/servicemanager
    class core
    user system
    group system
    critical
    onrestart restart healthd
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm

Class 为core 属于核心级的 它的主方法在service_manager.c中定义 我们看看它的实现:

frameworks/native/cmds/servicemanager/service_manager.c
int main(int argc, char **argv)
{
    struct binder_state *bs;
    void *svcmgr = BINDER_SERVICE_MANAGER;
	//打开binder 这里映射的内存大小为128k
    bs = binder_open(128*1024);
	//使sm成为所有服务的大管家
    if (binder_become_context_manager(bs)) {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }

    svcmgr_handle = svcmgr;
    binder_loop(bs, svcmgr_handler);//binder循环
    return 0;
}

进入主方法后,主要做了三件事: <1>. 打开binder驱动设备,servicemanager的业务并不复杂,这里映射的大小为128k。 <2>. 调用binder_become_context_manager使sevicemanger成为所有实名服务的大管家 <3>. 调用binder_loop进入binder循环,等待client端的请求。svcmgr_handler为servicemanager服务处理handler,它是一个函数指针,主要是处理它自身的业务逻辑。比如我们的client端通过AddService或者getService的服务就是在这里进行处理的。

下面我们分析servicemanager的binder_loop

frameworks/native/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));
	//不断的读取binder的内容
    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (unsigned) readbuf;

        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//读取binder内容

        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }

        res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);//解析数据
      ……
    }
}

Binder_loop中首先通过binder_write向Binder驱动写入BC_ENTER_LOOPER,表示进入binder循环,然后通过BINDER_WRITE_READ读取binder内容,结果存放在一个binder_write_read结构中,然后开始通过binder_parse解析数据,这里将我们的服务处理函数传递给它,那么数据应该是在这里交给我们的handler进行处理。

frameworks/native/cmds/servicemanager/binder.c
int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uint32_t *ptr, uint32_t size, binder_handler func)
{
    ……
        switch(cmd) {
        ……
	        case BR_TRANSACTION: {
	            struct binder_txn *txn = (void *) ptr;
	            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
	                ALOGE("parse: txn too small!\n");
	                return -1;
	            }
	            binder_dump_txn(txn);
	            if (func) {
	                unsigned rdata[256/4];
	                struct binder_io msg;
	                struct binder_io reply;
	                int res;
	
	                bio_init(&reply, rdata, sizeof(rdata), 4);
	                bio_init_from_txn(&msg, txn);
	                res = func(bs, txn, &msg, &reply);
	                binder_send_reply(bs, &reply, txn->data, res);
	            }
	            ptr += sizeof(*txn) / sizeof(uint32_t);
	            break;
	        }
	      ……
           }
    }
    return r;
}

可以看到在BR_TRANSACTION中的确是通过fun,也就是svcmgr_handler进行处理的。

//sm的服务handler
frameworks/native/cmds/servicemanager/service_manager.c
int svcmgr_handler(struct binder_state *bs,
                   struct binder_txn *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    struct svcinfo *si;
    uint16_t *s;
    unsigned len;
    void *ptr;
    uint32_t strict_policy;
    int allow_isolated;

    if (txn->target != svcmgr_handle)
        return -1;

    strict_policy = bio_get_uint32(msg);
    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, txn->sender_euid);
        if (!ptr)
            break;
        bio_put_ref(reply, ptr);
        return 0;

    case SVC_MGR_ADD_SERVICE:
        s = bio_get_string16(msg, &len);
        ptr = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, ptr, txn->sender_euid, allow_isolated))
            return -1;
        break;

    case SVC_MGR_LIST_SERVICES: {
        unsigned n = bio_get_uint32(msg);

        si = svclist;
        while ((n-- > 0) && si)
            si = si->next;
        if (si) {
            bio_put_string16(reply, si->name);
            return 0;
        }
        return -1;
    }
    default:
        ALOGE("unknown code %d\n", txn->code);
        return -1;
    }

    bio_put_uint32(reply, 0);
    return 0;
}

Servicemanager作为服务的大管家它的业务并不负责,相比其他service的服务可以说是异常简单,我们看看它最重要的服务即添加服务和获取服务。

Servicemanager维护了一个svclist链表,每个添加进来的服务都会通过一个svcinfo进行描述,并添加到链表中。它的结构如下

struct svcinfo 
{
    struct svcinfo *next;
    void *ptr;//service的句柄
    struct binder_death death;
    int allow_isolated;
    unsigned len;//服务名的长度
    uint16_t name[0];//服务名
};

struct svcinfo *svclist = 0;//sm内部维护了一个svclist列表它是已经注册的服务列表

我们看看查找服务的过程

void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len, unsigned uid)
{
    struct svcinfo *si;
    si = find_svc(s, len);
    if (si && si->ptr) {
        if (!si->allow_isolated) {
            // If this service doesn't allow access from isolated processes,
            // then check the uid to see if it is isolated.
            unsigned appid = uid % AID_USER;
            if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
                return 0;
            }
        }
        return si->ptr;
    } else {
        return 0;
    }
}

struct svcinfo *find_svc(uint16_t *s16, unsigned len)
{
    struct svcinfo *si;

    for (si = svclist; si; si = si->next) {
        if ((len == si->len) &&
            !memcmp(s16, si->name, len * sizeof(uint16_t))) {
            return si;
        }
    }
    return 0;
}

很简单,它在内部遍历链表,根据服务名进行查找如果找到返回对应的句柄si->ptr,否则返回0.

而添加服务的方法为do_add_service,它的实现如下

frameworks/native/cmds/servicemanager/service_manager.c
int do_add_service(struct binder_state *bs,
                   uint16_t *s, unsigned len,
                   void *ptr, unsigned uid, int allow_isolated)
{
    struct svcinfo *si;

    if (!ptr || (len == 0) || (len > 127))
        return -1;

    if (!svc_can_register(uid, s)) {
        ALOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED\n",
             str8(s), ptr, uid);
        return -1;
    }

    si = find_svc(s, len);
    if (si) {
        if (si->ptr) {
            ALOGE("add_service('%s',%p) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
                 str8(s), ptr, uid);
            svcinfo_death(bs, si);
        }
        si->ptr = ptr;
    } else {
        si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
        if (!si) {
            ALOGE("add_service('%s',%p) uid=%d - OUT OF MEMORY\n",
                 str8(s), ptr, uid);
            return -1;
        }
        si->ptr = ptr;
        si->len = len;
        memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
        si->name[len] = '\0';
        si->death.func = svcinfo_death;
        si->death.ptr = si;
        si->allow_isolated = allow_isolated;
        si->next = svclist;
        svclist = si;
    }

    binder_acquire(bs, ptr);
    binder_link_to_death(bs, ptr, &si->death);
    return 0;
}

添加服务的名称长度不能大于127,随后在svclist中查找服务是否已经存在,如果存在,则释放之前的服务实例,将最新的服务句柄赋值给ptr,否则服务不存在,就需要为新的服务创建svcinfo结构,并对其进行初始化。同时将其添加到svclist的头部。