之前在SeystemService的使用中有讲到ServiceManager的作用:查找获取和注册添加系统服务,但是由于那篇文章主要是梳理SystemService的使用,就没有对ServiceManager其他方面进行梳理.今天对ServiceManager的相关源码进行梳理;

Servicemanager的启动流程

我们从以下几个方面对Servicemanager的启动进行分析

启动进程和服务

获取servicemanager

向Servicemanager中添加服务

向servicemanager中查找获取服务

启动进程和服务

servicemanager也是个系统服务,但是他和一班的系统服务不一样,一般的系统服务是在SystemServer进程中的(AMS,PMS,WMS...),但是Servicemanager是个单独的进程, 

路径:/frameworks/native/cmds/servicemanager

├... ├── binder.c ├── binder.h ├── service_manager.c ├── servicemanager.rc └─....

在servicemanager.rc 文件中看到,(这是android 7 及以上版本把servicemanager.rc从init.rc中独立出来的,之前的版本ServiceManager 是由 init 进程通过解析 init.rc 文件而创建的,其所对应的可执行程序 /system/bin/servicemanager, 所对应的源文件是 service_manager.c,进程名为 servicemanager

service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    critical
    ...

servicemanager的主要实现在service_manager.c中,我们看他的main函数:

int main(int argc, char** argv)
{
    ...
    bs = binder_open(driver, 128*1024); // 打开Binder
    ...
    if (binder_become_context_manager(bs)) { // 把自己注册为Binder管理者
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
    ...
    binder_loop(bs, svcmgr_handler); // 进入loop.
    return 0;
}
int svcmgr_handler(...)
{
    ....
    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(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;
        dumpsys_priority = bio_get_uint32(msg);
        if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
                           txn->sender_pid))
            return -1;
        break;
 
    case SVC_MGR_LIST_SERVICES: {
       ...
    default:
        ALOGE("unknown code %d\n", txn->code);
        return -1;
    }
    bio_put_uint32(reply, 0);
    return 0;
}

main函数它主要做了三件事:

  • 打开Binder
  • 把自己注册为Binder管理者
  • 进入loop监听,使用svcmgr_handler来处理应用请求

获取servicemanager

系统服务要能够被使用,都需要提前拿到servicemanager,才能从servicemanager中查询和添加服务,那是怎么获取到servicemanager的呢?这里使用一个和servicemanager一样是单进程的系统服务SurfaceFlinger为例,看看系统服务是怎么拿到servicemanager,并向其添加注册自己的.

int main(int, char**) {
    ...
    // start the thread pool
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();

    // instantiate surfaceflinger
    sp<SurfaceFlinger> flinger = new SurfaceFlinger();
    ....
    // initialize before clients can connect
    flinger->init();

    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
    ...
    // run surface flinger in this thread
    flinger->run();

    return 0;
}

从上述关键的代码我们可以看到. 在这里使用defaultServiceManager()函数拉获取IServiceManager对象,我们继续看看defaultServicemanager怎么执行的:

sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}

在defaultServiceManager中,首先检查gDefaultServiceManager存不存在,如果存在就直接返回,如果不存在那就创建一个新的,怎么创建呢,就是 interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));

这里的ProcessState提供了self()方法,用于实例化ProcessState类.而在self()方法中执行了打开binder的操作,就是说拿到ProcessState的实例后就可以进行binder通信了;然后调用ProcessState的getContextObject()方法,最后将结果转换为IserviceManager,

getContextObject如下代码所示:getContextObject重视过去了一个Handler值为0的binder对象,[这里涉及binder,内容比较大先不继续,]Servicemanager他在binder中对应的Handler值就是0.段代码执行完,就可以理解成是获取到servicemanager,我们就可以操作servimanager了

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

向Servicemanager中添加服务

添加服务主要就是下面的代码所示,通过将服务写进parcel.然后和请求把服务加入到servicemanager中的请求码(ADD_SERVICE_TRAVSACTION)通过IPC调用,最后服务就会添加成功

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

向servicemanager中查找获取服务

获取服务和添加服务类似,都是通过binder调用,最后返回Ibinder,最后的操作都在service_manager.c的svcmgr_handler方法中根据不同的binder调用请求码进行处理的.然后封装成我们需要的系统服务.主要代码如下:

virtual sp<IBinder> getService(const String16& name) const
    {
        sp<IBinder> svc = checkService(name);
        if (svc != NULL) return svc;
        ...
    }  

virtual sp<IBinder> checkService( const String16& name) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
        return reply.readStrongBinder();
    }
int svcmgr_handler(...)
{
    ....
    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(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;
        dumpsys_priority = bio_get_uint32(msg);
        if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
                           txn->sender_pid))
            return -1;
        break;
 
    case SVC_MGR_LIST_SERVICES: {
       ...
    default:
        ALOGE("unknown code %d\n", txn->code);
        return -1;
    }
    bio_put_uint32(reply, 0);
    return 0;
}