ServiceManager是binder服务的管理者,服务端注册Binder,客户端获取binder都要通过ServiceManager,充当了一个binder路由转发的角色。

ServiceManager是一个独立的进程,在Java层提供了一个ServiceManager的接口类,真正的实现是在ServiceManager进程中

源码位置:frameworks/native/cmds/servicemanager/

主要逻辑实现:main.cppServiceManager.cpp

进程初始化

进程的初始化都在main函数里边,我们逐行分析

frameworks/native/cmds/servicemanager/main.cpp

int main(int argc, char** argv) {
    android::base::InitLogging(argv, android::base::KernelLogger);
    //binder驱动设备
    const char* driver = argc == 2 ? argv[1] : "/dev/binder";
    //生成ProcessState
    sp<ProcessState> ps = ProcessState::initWithDriver(driver);
    //禁用binder线程池,线程池数量设置为0
    ps->setThreadPoolMaxThreadCount(0);
    //初始化ServiceManager对象
    sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
    //将manager设置为contextObject,contextObject就是特指ServiceManager为全局管理对象
    IPCThreadState::self()->setTheContextObject(manager);
    //创建Looper对象,绑定线程,和java层的Looper原理一样
    sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
    //设置Callback
    sp<BinderCallback> binderCallback = BinderCallback::setupTo(looper);
    ClientCallbackCallback::setupTo(looper, manager, binderCallback);
    //开启无限循环监听binder驱动的事件消息
    while(true) {
        looper->pollAll(-1);
    }

    // should not be reached
    return EXIT_FAILURE;
}

进程模型

ServiceManager是一个单线程模型,所以没有开启binder线程池

监听binder驱动事件

普通进程开启了binder线程池,然后binder线程通过talkWithDriver陷入binder驱动中,等待binder驱动消息的到来再唤醒,那么serviceManager如何收到binder消息的呢?关键看BinderCallback


class BinderCallback : public LooperCallback {
public:
    static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
        sp<BinderCallback> cb = sp<BinderCallback>::make();
        cb->mLooper = looper;
        //将binderfd注册到epoll
        int ret = looper->addFd(cb->mBinderFd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
                                nullptr /*data*/);
        return cb;
    }
......
}

addFd函数内部调用的核心函数是

 epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, fd, &eventItem);

当进程调用looper->pollAll(-1);的时候就会发生休眠,pollAll函数内部调用的核心函数是

int Looper::pollInner(int timeoutMillis) {
    ......
    int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
    ......
}

epoll_wait发生阻塞

当有进程发起addService/getService请后,当驱动会写数据到binderFd,epoll_wait 检测到可读事件,唤醒Looper线程

读取binder事件

ServiceMnager线程唤醒

Looper线程被唤醒后,调用handleEvent

int Looper::pollInner(int timeoutMillis) {
    ......
    int callbackResult = response.request.callback->handleEvent(fd, events, data);
    ......
}

然后回到我们上面的callback对象中

class BinderCallback : public LooperCallback {
public:
    ......
    int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
        IPCThreadState::self()->handlePolledCommands();
        return 1;  // Continue receiving callbacks.
    }
}

handlePolledCommands函数简单调用IPCThreadState::getAndExecuteCommand, 后续的逻辑就和普通进程中的binder线程池读取binder数据一样了

对比Binder线程池的处理方式

所以,Looper的作用是监听Binder驱动的读写事件,如果binder收到对于ServiceManager的事务请求,比如addService,那么looper线程将被唤醒,然后调用IPCThreadState::talkWithDriver去读取驱动的todo队列来处理addService事务,而普通的binder线程池则是先调用talkWithDriver陷入内核休眠,然后todo队列有了事务直接唤醒线程,事情处理完后通过while(true)陷入无限循环中的下一次talkWithDriver等待事务的到来。

维度

普通Binder服务(如system_server中的服务)

ServiceManager

事件循环方式

直接调用 IPCThreadState::joinThreadPool() → 循环内 talkWithDriver()

使用 Looper 框架,将binder fd注册到 epoll

线程阻塞位置

阻塞在 ioctl(BINDER_WRITE_READ) 系统调用内部(驱动层)

阻塞在 epoll_wait() 系统调用(用户态/内核态边界)

唤醒触发

驱动有事务时,直接唤醒正在 binder_thread_read 中睡眠的线程

驱动写数据到binder fd,epoll_wait 检测到可读事件,唤醒Looper线程

数据读取时机

被唤醒后,ioctl 返回,数据已在内核缓冲区,用户态直接读取

Looper回调中主动调用 talkWithDriver() 读取驱动数据

可扩展性

只能处理Binder事务

可同时监听多个fd(如socket、eventfd),但目前只用binder fd

Java对外接口

ServiceManager是单独的进程,其他进程要查询/注册binder服务也要发起跨进程通信,他们的接口是什么呢?

以addService为例子在Java层的ServiceManager接口中有这样的调用

public static void addService(String name, IBinder service, boolean allowIsolated,
        int dumpPriority) {
    try {
        getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
}

getIServiceManager会返回一个C++层的ServiceManager的binder代理对象

ServiceManager代理对象的获取

private static IServiceManager getIServiceManager() {

    // Find the service manager
    sServiceManager = ServiceManagerNative
            .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}

    public static IServiceManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }

        // ServiceManager is never local
        return new ServiceManagerProxy(obj);
    }


class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
        mServiceManager = IServiceManager.Stub.asInterface(this.getNativeServiceManager());
    }

    public IBinder asBinder() {
        return mRemote;
    }

    public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
            throws RemoteException {
        mServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }
}

从上面的调用链来看,核心函数应该是ServiceManagerProxy构造函数中的

mServiceManager = IServiceManager.Stub.asInterface(this.getNativeServiceManager());

那个mRemote对象没用,将来会被删除,这里是基于Android 15的源码,所以看起来还有冗余的代码

getNativeServiceManager返回的就是ServiceManager代理对象,jni将其封装成了BInderProxy

ServiceManager代理对象BinderProxy在native层做了几次封装,最初始的对象是BpServiceManager,然后封装成BackendUnifiedServiceManager,最后java对象BinderProxy包含了指向native对象的指针。

BpServiceManager是什么?这得看看C++层的AIDL接口了,它类似java层AIDL生成的Binder.Stub.Proxy类

C++对外接口

ServiceManager作为一个binder来使用,必定有binder代理和binder实体,先看看类图

classDiagram class RefBase { <<Android 基类>> +incStrong() +decStrong() } class IBinder { <<interface>> +transact() +linkToDeath() } class BBinder { +transact() +onTransact() } class IInterface { <<interface>> +asBinder() } class IServiceManager { <<interface>> +addService() +getService() } class BnInterface~IServiceManager~ { <<template>> } class BnServiceManager { +onTransact() } class ServiceManager { +addService() +getService() +binderDied() } RefBase <|-- BBinder RefBase <|-- BnInterface~IServiceManager~ IBinder <|-- BBinder BBinder <|-- BnInterface~IServiceManager~ IInterface <|-- IServiceManager IServiceManager <|.. BnInterface~IServiceManager~ BnInterface~IServiceManager~ <|-- BnServiceManager BnServiceManager <|-- ServiceManager note for ServiceManager "位于 frameworks/native/cmds/servicemanager/ServiceManager.cpp" note for BnServiceManager "由 IServiceManager.aidl 自动生成"classDiagram class RefBase class IBinder { <<interface>> +transact() } class BpBinder { +transact() } class BpRefBase { #mRemote : IBinder* +remote() : IBinder* } class IInterface { <<interface>> +asBinder() } class IServiceManager { <<interface>> +getService() +addService() } class BpInterface~IServiceManager~ { <<template>> } class BpServiceManager { +getService() +addService() } RefBase <|-- BpBinder RefBase <|-- BpRefBase IBinder <|-- BpBinder BpRefBase *-- BpBinder : mRemote BpRefBase <|-- BpInterface~IServiceManager~ IInterface <|-- IServiceManager IServiceManager <|.. BpInterface~IServiceManager~ BpInterface~IServiceManager~ <|-- BpServiceManager

在Native中,也有一套类似Java层的AIDL接口标准,编译器会自动生成IServiceManager.cpp文件,包含两个类,BpServiceManager和BnServiceManager

main函数中初始化的ServiceManager为binder实体对象,继承自BnServiceManager,定义如下

class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {
public:
    ServiceManager(std::unique_ptr<Access>&& access);
    ~ServiceManager();
}

当驱动的指令下来,经过下面的调用栈,最终走到ServiceManager类

IPCThreadState::handlePolledCommands()
   IPCThreadState::getAndExecuteCommand()
      IPCThreadState::talkWithDriver(bool doReceive)
      IPCThreadState::executeCommand(int32_t cmd)
         BBinder::transact()
            BnServiceManager::onTransact
               ServiceManager::addService()

Java的AIDL也有上面类似的调用链,区别是java是从binder线程池开始的,而servicemanager是从主线程looper发起的

春风花气馥,秋月寒江湛