Android Framework:Binder(2)-Service Manager

本文主要讲述binder机制中重要的管理员角色ServiceManager学习理解(本文源码参考Android N 7.1.1 )

一、binder机制的主要框架

Android BootCompletedReceiver不起作用 安卓bootmanager_framework

由上图看出,ServiceManager是Service的管理员,作用十分重要:
1.对于Service来说,系统所有的服务都需要向ServiceManager注册;
2.对于Client来说,所有Client需要使用系统服务时,必须向ServiceManager申请获取相应的服务端代理。

二、 Native层ServiceManager

我们从源码分析Native 层 ServiceManager的启动流程和服务流程。

1. ServiceManager启动:

init.rc中将触发early-boot和boot阶段。

system/core/rootdir/init.rc
on late-init
    trigger early-boot
    trigger boot

在boot阶段的最后,进行class_start core的操作

on boot
    .......
    class_start core

在system/core/init/builtins.cpp中,class_start对应的处理函数是do_class_start:

static int do_class_start(const std::vector<std::string>& args) {
    //此时,args为“core”
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
    return 0;
}

将对service对象中class字段等于“core”的所有服务,执行StartIfNotDisabled操作。

bool Service::StartIfNotDisabled() {
    if (!(flags_ & SVC_DISABLED)) {
        //启动服务
        return Start();
    } else {
        flags_ |= SVC_DISABLED_START;
    }
    return true;
}

bool Service::Start() {
    //参数检查等操作
    ..........
    pid_t pid = fork();
    if (pid == 0) {
        //fork出子进程后,为子进程设置参数
        ......
        //启动对应的main函数
        if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) {
            ..............
        }
    }
    ......
}

执行service_manager.c的main函数则ServiceManager便启动起来,值得注意的是,ServiceManager是独立的进程,是init进程的子进程。而Zygote进程的class字段为main,启动顺序在servicemanager之后。

2. Native层的service_manager初始化

Native层的service_manager的main函数在frameworks/native/cmds/servicemanager/service_manager.c中定义,接着上面,我们来看看service_manager.c启动的时候main函数都做了什么:

frameworks/native/cmds/servicemanager/service_manager.c
int main()
{
    struct binder_state *bs;
    union selinux_callback cb;
    //1.打开binder驱动,在内存映射128k
    bs = binder_open(128*1024);
    ...
    //2.设置自己为service manager
    if (binder_become_context_manager(bs)) {
        ...
    }
    //3.selinux相关操作
    ...
    //4.进入循环处理请求
    binder_loop(bs, svcmgr_handler);
}
2.1 打开binder驱动设备 binder_open()
frameworks/native/cmds/servicemanager/binder.c
struct binder_state *binder_open(size_t mapsize)
{
    //创建binder_state结构体并分配内存 
    struct binder_state *bs;
    struct binder_version vers;
    bs = malloc(sizeof(*bs));
    if (!bs) {
        errno = ENOMEM;
        return NULL;
    }
    //打开binder设备,应该就是一个文件
    bs->fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
    ...
    //判断内核版本和用户空间的版本是否一致
    if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
        (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
        ...
    }
    //完成内存映射
    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

    return bs; //返回binderstate结构体给ServiceManager
}
.......................................................
//binder_state数据结构:
binder.c
struct binder_state
{
    int fd; //binder文件句柄,binder设备文件描述符
    void *mapped;//把设备文件/dev/binder映射到进程空间的起始地址
    size_t mapsize;//映射的空间大小  
};
2.2 ServiceManager成为服务管理员 binder_become_context_manager()

Android里,每个service注册时,binder都会给它关联一个handle值,客户端可以根据服务的handle值向ServiceManager请求对应的服务代理,负责这个管理任务的就是ServiceManager。ServiceManager将自己的handle值设置为0,于是其它的进程与其通信时,不需要进行额外的查询

int binder_become_context_manager(struct binder_state *bs)
{
    //将ServiceManager对应的binder句柄handle设置为0
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
2.3 Service_manager开始服务管理 binder_loop
binder.c
void binder_loop(struct binder_state *bs, binder_handler func)
{

    //告诉binder驱动,servicemanager准备进入循环
    readbuf[0] = BC_ENTER_LOOPER;
    binder_write(bs, readbuf, sizeof(uint32_t));
    //进入循环处理
    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;
        // 向binder驱动去查询是否有向自己发的请求
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
        ...
        // 当收到数据后,利用binder_parse解析数据,然后调用func处理,此处func为svcmgr_handler
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
        ...
    }
}

看到service_manager.c的初始化main函数主要做了如下操作:

Android BootCompletedReceiver不起作用 安卓bootmanager_ci_02

3 ServiceManager处理消息请求

3.1 解析消息请求

下面来看下binder_looper中是如何使用binder_parse()处理请求的:

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;

    while (ptr < end) {
        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: { //service onTransaction
            struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
            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);
                //调用service_manager.c中的svcmgr_handler去处理数据 
                res = func(bs, txn, &msg, &reply);
                if (txn->flags & TF_ONE_WAY) {
                    binder_free_buffer(bs, txn->data.ptr.buffer);
                } else {
                    //将Service_manager对客户端的回应数据(reply)返回给Binder驱动 
                    binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
                }
            }
            ptr += sizeof(*txn);
            break;
        }
        case BR_REPLY: 
        case BR_DEAD_BINDER:
        //如果与serviceManager通信的binder死亡,需要调用对应的处理函数
            death->func(bs, death->ptr); 
        case BR_FAILED_REPLY:
        case BR_DEAD_REPLY:
        default:
            ALOGE("parse: OOPS %d\n", cmd);
            return -1;
        }
    }

    return r;
}

binder_loop(bs, svcmgr_handler); 中使用svcmgr_handler去处理servicemanager从binder驱动中拿到的请求,然后把返回值作为回应通过binder_send_reply()函数返回给客户端。

int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply) {
    //进行参数有效性检查等操作
    .............
    //根据收到数据中携带的code字段,执行相应的操作
    switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        //从收到数据中读出需查找服务的名称,得到一个Service
        s = bio_get_string16(msg, &len);
        .......
        //得到服务对应的句柄
        //根据名称进行匹配,在返回信息前会进行权限检查
        handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);//查找服务的handle
        ......
        //将查找服务的handle信息写入reply
        bio_put_ref(reply, handle);
        return 0;

    case SVC_MGR_ADD_SERVICE:
        s = bio_get_string16(msg, &len);
        .......
        handle = bio_get_ref(msg);//获取handle
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        //向servicemanager注册服务,添加一个服务
        //在注册前会进行权限检查,然后利用参数中的信息,构建出服务对象,加入到全局变量svclist中
        //同时会调用binder_link_to_death监听新加入服务进程是否死亡
        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, txn->sender_euid)) {
            //log
            ......
            return -1;
        }

        //svclist中记录了注册到servicemanager的服务的信息
        si = svclist;
        while ((n-- > 0) && si)
            si = si->next;
        if (si) {
            //得到当前注册到servicemanager的服务中,第n个服务的名称
            bio_put_string16(reply, si->name);
            return 0;
        }
        return -1;
    }
    .............
}

从svcmgr_handler的case分支我们可以看出,作为Service_manager主要完成三个功能:
1、得到一个Service;
2、添加一个Service;
3、列出所有的Service;

3.1.1 查找服务 do_find_service
frameworks/native/cmds/servicemanager/service_manager.c
uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid)
{
    struct svcinfo *si = find_svc(s, len);

    if (!si || !si->handle) {
        return 0;
    }
    //检查是否有权限获取该服务
    if (!si->allow_isolated) {
        // If this service doesn't allow access from isolated processes,
        // then check the uid to see if it is isolated.
        uid_t appid = uid % AID_USER;
        if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
            return 0;
        }
    }
    //继续跟下去可以看到是selinux权限检测
    if (!svc_can_find(s, len, spid, uid)) {
        return 0;
    }
    //返回该name的service的handle值
    return si->handle;
}

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

    for (si = svclist; si; si = si->next) { //在svclist中寻找s对应的svcinfo,并返回该service name的svcinfo
        if ((len == si->len) &&
            !memcmp(s16, si->name, len * sizeof(uint16_t))) {
            return si;
        }
    }
    return NULL;
}
3.1.2 添加服务
int do_add_service(struct binder_state *bs,
                   const uint16_t *s, size_t len,
                   uint32_t handle, uid_t uid, int allow_isolated,
                   pid_t spid)
{
    struct svcinfo *si;
    //看spid,uid是否有权限进行添加service的操作,跟下看有selinux相关的权限检查
    if (!svc_can_register(s, len, spid, uid)) {
        return -1;
    }
    //检查该服务是否已经注册
    si = find_svc(s, len);
    if (si) {
        if (si->handle) {
            ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
                 str8(s, len), handle, uid);
            svcinfo_death(bs, si);
        }
        si->handle = handle;
    } else {
        si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
        if (!si) {
            ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",
                 str8(s, len), handle, uid);
            return -1;
        }
        si->handle = handle;//唯一的handle去关联
        si->len = len;
        memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
        si->name[len] = '\0';
        si->death.func = (void*) svcinfo_death;
        si->death.ptr = si;
        si->allow_isolated = allow_isolated;
        si->next = svclist;
        svclist = si;//将该服务添加址svclist中,及完成service的注册
    }

    binder_acquire(bs, handle);
    binder_link_to_death(bs, handle, &si->death);
    return 0;
}
3.1.3 列出所有的服务

list Service的请求只需要把svclist返回给Client即可;由上我们知道所有注册的service信息都在全局list变量中svclist;
至此ServiceManager就完成了解析数据的过程

3.2 将解析的结构返回至binder驱动

在3.1中的三个请求处理过程中,特别是get和list Service的请求,最终都需要给客户端相应回应的,我们看到在这两个请求的处理最后,都将相应的回应数据放入了reply的指针中,当从svcmgr_handler()返回后,就把数据带到了binder_parse()中,我们再来回顾一下这里的代码:

int binder_parse(struct binder_state *bs,struct binder_io *bio,uint32_t *ptr,uint32_t size,binder_handler func){  
    while (ptr < end) {  
        switch(cmd) {  
            case BR_TRANSACTION: {  
                struct binder_txn *txn = (void *) ptr;  
                binder_dump_txn(txn);  
                if (func) {  
                    //reply就是svcmgr_handler()中得到的回应  
                    res = func(bs, txn, &msg, &reply);  
                    //将回应数据(reply)返回给Binder驱动  
                    binder_send_reply(bs, &reply, txn->data, res);  
                }  
                ptr += sizeof(*txn) / sizeof(uint32_t);  
                break;  
            }  
        }  
    }  
    return r;  
}

在binder_parse()中又调用binder_send_reply()函数完成回应的操作:

void binder_send_reply(struct binder_state *bs,
                       struct binder_io *reply,
                       binder_uintptr_t buffer_to_free,
                       int status)
{
    struct {
        uint32_t cmd_free;
        binder_uintptr_t buffer;
        uint32_t cmd_reply;
        struct binder_transaction_data txn;
    } __attribute__((packed)) data;

    data.cmd_free = BC_FREE_BUFFER;
    data.buffer = buffer_to_free;
    data.cmd_reply = BC_REPLY;
    data.txn.target.ptr = 0;
    data.txn.cookie = 0;
    data.txn.code = 0;
    if (status) {
        data.txn.flags = TF_STATUS_CODE;
        data.txn.data_size = sizeof(int);
        data.txn.offsets_size = 0;
        data.txn.data.ptr.buffer = (uintptr_t)&status;
        data.txn.data.ptr.offsets = 0;
    } else {
        data.txn.flags = 0;
        data.txn.data_size = reply->data - reply->data0;
        data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
        data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
        data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
    }
    //向binder驱动写回应数据
    binder_write(bs, &data, sizeof(data));
}

在给Binder发送返回值时,构建了data的数据,并把reply放入其中,并标记了数据的大小,最后通过binder_write()函数将数据写到Binder中,而且写的方法仍然是调用ioctl()。

binder.c
 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;
    bwr.read_size = 0;
    bwr.read_consumed = 0;
    bwr.read_buffer = 0;
    //使用ioctl方式将会有的数据写到该service的binder驱动中
    res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    return res;
    }
3.3 ServiceManager循环处理消息的大致流程图如下:

Android BootCompletedReceiver不起作用 安卓bootmanager_数据_03

三、 Java层ServiceManager

在frameworks/base/core/java/android/os/ServiceManager.java定义了java层的ServiceManager
我们看到这里定义的函数有:

private static IServiceManager getIServiceManager() ;//获取ServiceManager实例
    public static IBinder getService(String name) ;//获取服务端的binder,即服务端代理
    public static void addService(String name, IBinder service) ;//添加服务
    public static void addService(String name, IBinder service, boolean allowIsolated) {
    public static IBinder checkService(String name) ;
    public static String[] listServices() {
    ...

java层service的管理同样需要经过java层的serviceManager,我们看看几个例子:
AMS启动时

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setSystemProcess() {
        try {
                ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
                ...
            }

PMS启动时

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        ServiceManager.addService("package", m);
        return m;
    }

获取Service的binder对象:
如ClipboardService的获取

frameworks/base/core/java/android/content/ClipboardManager.java
    static private IClipboard getService() {
        synchronized (sStaticLock) {
            if (sService != null) {
                return sService;
            }
            IBinder b = ServiceManager.getService("clipboard");
            sService = IClipboard.Stub.asInterface(b);
            return sService;
        }
    }

事实上Java层的ServiceManager是Native层ServiceManager的一个Client,而对于Java层其他Service来说,Java层的ServiceManager又是一个Service,负责把其他Client的请求转发给Native层的ServiceManager去处理。Java层的服务注册查询同样也要经过java层的ServiceManager,继而通过JNI方式通过native层的ServiceManager,具体实现方式将在日后的Binder的Java层进行详细的学习阐述。

先简单用图表示:

Android BootCompletedReceiver不起作用 安卓bootmanager_ci_04

四、总结

  1. ServiceManger的Native层主要在frameworks/native/cmds/servicemanager/service_manager.c,其作用举足轻重,是所有服务的管理员。
  2. ServiceManager是init进程的子进程,init进程启动之后会按顺序最终启动ServiceManager,而zygote进程还在ServiceManager进程之后。
  3. Service被使用前需要向ServiceManager中注册自己,我们在service_manager.c中的svcmgr_handler函数中看到,服务端注册事实上是通过ServiceManager生成一个唯一的handle值与该服务关联,并将该服务的信息加到全局变量svclist中及完成注册;而当客户端调用服务的时候会去向 Service Manager查询该服务是否存在,若svclist存在该服务的信息时ServiceManager会返回该服务关联的handle,之后客户端通过该handle获取服务端的代理,将在下面的文章再详细分析。
  4. Java层的ServiceManager就是Native层ServiceManager的一个Client,而对于Java层其他Service来说,Java层的ServiceManager又是一个Service,负责把其他Client的请求转发给Native层的ServiceManager去处理。