Android Service 的添加流程

来源:互联网 发布:福师大网络与继续教育 编辑:程序博客网 时间:2024/05/11 21:14

Android  系统层会在开机会加载启动各种服务,下面以MediaPlayerServer为例,如查看init.rc文件cat  init.rc,可以看到Media进程的启动。

service media /system/bin/mediaserver    class main    user media    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc    ioprio rt 4

1 . 向ServiceManager添加服务

main_mediaserver.cpp添加"media.player"服务到ServiceManager中         

void MediaPlayerService::instantiate() {    defaultServiceManager()->addService(            String16("media.player"), new MediaPlayerService());}

2. IServiceManager 派生对象BpServiceManager 代理添加

    virtual status_t BpServiceManager::addService(const String16& name, const sp<IBinder>& service)    {        Parcel data, reply;        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());        data.writeString16(name);        data.writeStrongBinder(service);        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);        return err == NO_ERROR ? reply.readExceptionCode() : err;    }

3. BnServiceManager 完成向ServiceManager添加

status_t BnServiceManager::onTransact(    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    switch(code) {<span style="white-space:pre"></span>......        case ADD_SERVICE_TRANSACTION: {            CHECK_INTERFACE(IServiceManager, data, reply);            String16 which = data.readString16();            sp<IBinder> b = data.readStrongBinder();            status_t err = addService(which, b);            reply->writeInt32(err);            return NO_ERROR;        } break;        default:            return BBinder::onTransact(code, data, reply, flags);    }}

4. addService 通过IPC通信传递给ServiceManager主线程binder_loop

          

void binder_loop(struct binder_state *bs, binder_handler <span style="color:#FF0000;">func</span>){    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 = <span style="color:#FF6666;">binder_parse</span>(bs, 0, readbuf, bwr.read_consumed, <span style="color:#FF0000;">func</span>);        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;        }    }}

5.binder_parse解析动Binder获取到的信息,然后调用svcmgr_handler

int svcmgr_handler(struct binder_state *bs,                   struct binder_txn *txn,                   struct binder_io *msg,                   struct binder_io *reply){     .........     switch(txn->code) {    .........    case <span style="color:#FF0000;">SVC_MGR_ADD_SERVICE</span>:        s = bio_get_string16(msg, &len);        ptr = bio_get_ref(msg);        if (<span style="color:#FF0000;">do_add_service</span>(bs, s, len, ptr, txn->sender_euid))            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:        LOGE("unknown code %d\n", txn->code);        return -1;    }    bio_put_uint32(reply, 0);    return 0;}

6. do_add_service将最终的media.player服务添加到全局Service  链表svclist中

int do_add_service(struct binder_state *bs,                   uint16_t *s, unsigned len,                   void *ptr, unsigned uid){    struct svcinfo *si;//    LOGI("add_service('%s',%p) uid=%d\n", str8(s), ptr, uid);    if (!ptr || (len == 0) || (len > 127))        return -1;    if (!svc_can_register(uid, s)) {        LOGE("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) {            LOGE("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) {            LOGE("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->next = svclist;        svclist = si;    }    binder_acquire(bs, ptr);    binder_link_to_death(bs, ptr, &si->death);    return 0;}

  

        


0 0