framework学习笔记

framework 学习笔记6. ServiceManager进

2020-12-09  本文已影响0人  加个标志位

一. ServiceManager进程是init进程解析init.rc启动的第一个服务进程,涉及到的源代码有framework/native/cmd/servicemanager目录下的 service_manager.c和binder.c ,这里的binder.c并不是binder驱动代码,而属于native层的代码;
首先进入main()方法,一共分三步:
a. 打开binder驱动;
b. 成为binder驱动管理者;
c. 循环等待处理client请求;
这三步对应的调用了framework/native/cmd/servicemanager包下的binder.c中的三个方法,详情如下:

int main(int argc, char **argv){
    struct binder_state *bs;
    bs = binder_open(128*1024);  //a打开binder驱动;
    if (!bs) {
        ALOGE("failed to open binder driver\n");
        return -1;
    }
    if (binder_become_context_manager(bs)) {  //成为binder驱动管理者;
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
    selinux_enabled = is_selinux_enabled();
    sehandle = selinux_android_service_context_handle();
    if (selinux_enabled > 0) {
        if (sehandle == NULL) {
            ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
            abort();
        }
        if (getcon(&service_manager_context) != 0) {
            ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
            abort();
        }
    }
    union selinux_callback cb;
    cb.func_audit = audit_callback;
    selinux_set_callback(SELINUX_CB_AUDIT, cb);
    cb.func_log = selinux_log_callback;
    selinux_set_callback(SELINUX_CB_LOG, cb);
    svcmgr_handle = BINDER_SERVICE_MANAGER;
    binder_loop(bs, svcmgr_handler);  //c循环等待处理client请求;

    return 0;
}

  1. 打开Binder驱动:binder_open(128*1024),大小为128kb;
struct binder_state *binder_open(size_t mapsize){
    struct binder_state *bs;
    struct binder_version vers;
    bs = malloc(sizeof(*bs));
    if (!bs) {
        errno = ENOMEM;
        return NULL;
    }
    //打开驱动,调用的是驱动层的binder_open()
    bs->fd = open("/dev/binder", O_RDWR);
    if (bs->fd < 0) {
        fprintf(stderr,"binder: cannot open device (%s)\n",
                strerror(errno));
        goto fail_open;
    }
    // 获取binder驱动的版本,ioctl()==>binder_ioctl()
    if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
        (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
        fprintf(stderr, "binder: driver version differs from user space\n");
        goto fail_open;
    }
    //调用的是驱动层的binder_mmap()
    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;
    }
    return bs;
}

  1. 成为binder驱动管理者:binder_become_context_manager()
// 通知驱动,当前进程成为驱动层的管理者,调用的也是binder_ioctl();
int binder_become_context_manager(struct binder_state *bs){
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
  1. 循环等待处理client请求
void binder_loop(struct binder_state *bs, binder_handler func){
    int res;
    struct binder_write_read bwr; //这个结构体在笔记5中有说明
    uint32_t readbuf[32];
    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;
    readbuf[0] = BC_ENTER_LOOPER;   // BC_ENTER_LOOPER指令
    binder_write(bs, readbuf, sizeof(uint32_t));  //见3.1

    for (;;) {  //这是一共死循环---核心代码 
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;
        //会进入等待,如果有别的进程通过binder_ioctl()写入了数据,这里就会唤醒;
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }
        //获取到数据后,进行解析  3.2
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);  
        if (res == 0) {
            ALOGE("binder_loop: unexpected reply?!\n");
            break;
        }
        if (res < 0) {
            ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
            break;
        }
    }
}

3.1 framework/native/cmd/servicemanager/binder.c中的binder_write(bs, readbuf, sizeof(uint32_t))方法:
参数定义:
a. bs = binder_open(128*1024);
b. readbuf[0] = BC_ENTER_LOOPER;
c. sizeof(uint32_t) 4字节;

int binder_write(struct binder_state *bs, void *data, size_t len){
    struct binder_write_read bwr;
    int res;
    bwr.write_size = len;
    bwr.write_consumed = 0;
    bwr.write_buffer = (uintptr_t) data;
    //写入数据的时候,不需要读,read方面的全为0;驱动根据write_size>0写入,read_size>0读取;
    bwr.read_size = 0;
    bwr.read_consumed = 0;
    bwr.read_buffer = 0;
    res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); // ioctl()方法;
    if (res < 0) {
        fprintf(stderr,"binder_write: ioctl failed (%s)\n",
                strerror(errno));
    }
    return res;
}

3.2 binder_parse()方法;
uintptr_t ptr : 首地址

int binder_parse(struct binder_state *bs, struct binder_io *bio, uintptr_t ptr, size_t size, binder_handler func){
    int r = 1;
    uintptr_t end = ptr + (uintptr_t) size;  // 根据首地址和size确定end;

    while (ptr < end) {
        // cmd命令,笔记5中有分析到,当然这里的命令不是原封不动的笔记5中的BC_TRANSACTION命令了,binder驱动会有一                
        //个转化===>BR_TRANSACTION
uint32_t cmd = *(uint32_t *) ptr;    
        ptr += sizeof(uint32_t);

        switch(cmd) {
        case BR_NOOP:
            break;
        case BR_TRANSACTION_COMPLETE:
            break;
        case BR_INCREFS:
        case BR_ACQUIRE:
        case BR_RELEASE:
        case BR_DECREFS:

            ptr += sizeof(struct binder_ptr_cookie);
            break;
        case BR_TRANSACTION: {
            struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
            if ((end - ptr) < sizeof(*txn)) {
                ALOGE("parse: txn too small!\n");
                return -1;
            }
            binder_dump_txn(txn);
            if (func) {  //这个func是回调函数,如果有,则回调回去;
                unsigned rdata[256/4];
                struct binder_io msg;
                struct binder_io reply;
                int res;

                bio_init(&reply, rdata, sizeof(rdata), 4);    // 初始化,通过binder io 来管理这一块内存;
                bio_init_from_txn(&msg, txn);    // 数据赋值操作;
                res = func(bs, txn, &msg, &reply);    //方法回调,真正处理业务逻辑的核心地方
                binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);//发送应答数据
            }
            ptr += sizeof(*txn);
            break;
        }
        case BR_REPLY: {
            struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
            if ((end - ptr) < sizeof(*txn)) {
                ALOGE("parse: reply too small!\n");
                return -1;
            }
            binder_dump_txn(txn);
            if (bio) {
                bio_init_from_txn(bio, txn);    //初始化,通过binder io 来管理这一块内存;
                bio = 0;
            } else {
                /* todo FREE BUFFER */
            }
            ptr += sizeof(*txn);
            r = 0;
            break;
        }
        case BR_DEAD_BINDER: {
            struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr;
            ptr += sizeof(binder_uintptr_t);
            death->func(bs, death->ptr);
            break;
        }
        case BR_FAILED_REPLY:
            r = -1;
            break;
        case BR_DEAD_REPLY:
            r = -1;
            break;
        default:
            ALOGE("parse: OOPS %d\n", cmd);
            return -1;
        }
    }
    return r;
}

回调方法分析

int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply){
    struct svcinfo *si;
    uint16_t *s;
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
    int allow_isolated;

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

    if (txn->code == PING_TRANSACTION)
        return 0;

    strict_policy = bio_get_uint32(msg);
    s = bio_get_string16(msg, &len);
    if (s == NULL) {
        return -1;
    }

    if ((len != (sizeof(svcmgr_id) / 2)) ||
        memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {  //svcmgr_id是android.os.iservicemanager
        fprintf(stderr,"invalid id %s\n", str8(s, len));
        return -1;  //如果不是传给iservicemanager,则返回
    }

    if (sehandle && selinux_status_updated() > 0) {
        struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
        if (tmp_sehandle) {
            selabel_close(sehandle);
            sehandle = tmp_sehandle;
        }
    }

    switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
        if (!handle)
            break;
        bio_put_ref(reply, handle);
        return 0;

    case SVC_MGR_ADD_SERVICE:  //添加服务
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        //do_add_service()中的sender_pid是pid_t,用来检验权限
        if (do_add_service(bs, s, len, handle, txn->sender_euid,allow_isolated, txn->sender_pid))                                           
            return -1;
        break;

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

        if (!svc_can_list(txn->sender_pid)) {
            ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
                    txn->sender_euid);
            return -1;
        }
        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.PNG
上一篇下一篇

猜你喜欢

热点阅读