Android跨进程通信下:Server端调度流程分析

467 阅读6分钟

ServiceManager的启动流程与核心机制

一、ServiceManager的进程与继承体系

ServiceManager继承

  • ServiceManager是独立的系统进程,启动时机早于Zygote,在init.rc中配置。
  • 其service.rc文件列出了ServiceManager相关服务及依赖:

service.rc内容

:如果ServiceManager重启,将导致诸如healthd、zygote等关键服务一并重启。


二、ServiceManager主流程源码梳理

main函数

int main(int argc, char** argv) {
    // 参数判断与Binder驱动路径选择
    if (argc > 2) {
        LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
    }
    const char* driver = argc == 2 ? argv[1] : "/dev/binder";
    // (1) 初始化Binder驱动
    sp<ProcessState> ps = ProcessState::initWithDriver(driver);
    ps->setThreadPoolMaxThreadCount(0);
    ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
    // 实例化ServiceManager
    sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
    // 自注册
    if (!manager->addService("manager", manager, false, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
        LOG(ERROR) << "Could not self register servicemanager";
    }
    // (2) 设置上下文对象
    IPCThreadState::self()->setTheContextObject(manager);
    // 成为Binder驱动的context manager
    ps->becomeContextManager(nullptr, nullptr);
    // Looper初始化,监听Binder事件
    sp<Looper> looper = Looper::prepare(false);
    BinderCallback::setupTo(looper);
    // (3) 注册监听
    ClientCallbackCallback::setupTo(looper, manager);

    while(true) {
        looper->pollAll(-1);
    }
    return EXIT_FAILURE; // 不应该到达这里
}
  • 说明

    1. 首先初始化Binder驱动
    2. 创建ServiceManager对象并自注册
    3. 设置为全局context对象,成为Binder的上下文管理者
    4. 使用Looper监听Binder fd,进行事件分发
    5. 死循环poll,持续处理Binder事务

线程本地存储与IPCThreadState

// IPCThreadState线程本地单例获取
IPCThreadState* IPCThreadState::self() {
    if (gHaveTLS.load(std::memory_order_acquire)) {
    restart:
        const pthread_key_t k = gTLS;
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) return st;
        return new IPCThreadState;
    }
    if (gShutdown.load(std::memory_order_relaxed)) {
        ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
        return nullptr;
    }
    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS.load(std::memory_order_relaxed)) {
        int key_create_value = pthread_key_create(&gTLS, threadDestructor);
        if (key_create_value != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
                    strerror(key_create_value));
            return nullptr;
        }
        gHaveTLS.store(true, std::memory_order_release);
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart;
}
  • 重点:IPCThreadState通过TLS(线程本地存储)实现线程隔离的状态管理,本质上和Java的ThreadLocal非常相似。

BinderCallback实现(监听事件分发)

class BinderCallback : public LooperCallback {
public:
    static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
        sp<BinderCallback> cb = new BinderCallback;
        int binder_fd = -1;
        IPCThreadState::self()->setupPolling(&binder_fd);
        LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd);
        IPCThreadState::self()->flushCommands();
        int ret = looper->addFd(binder_fd, Looper::POLL_CALLBACK,
                                Looper::EVENT_INPUT, cb, nullptr);
        LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");
        return cb;
    }

    int handleEvent(int, int, void*) override {
        IPCThreadState::self()->handlePolledCommands();
        return 1;
    }
};
  • 说明:核心作用就是监听Binder fd,一旦有事件发生即调用handlePolledCommands处理命令。

Binder消息处理流程

IPCThreadState里:

status_t IPCThreadState::handlePolledCommands() {
    status_t result;
    do {
        result = getAndExecuteCommand();
    } while (mIn.dataPosition() < mIn.dataSize());
    processPendingDerefs();
    flushCommands();
    return result;
}

status_t IPCThreadState::getAndExecuteCommand() {
    // ...省略读取cmd
    result = executeCommand(cmd);
    return result;
}
  • 说明:循环读取、解析、执行来自Binder驱动的所有命令,直至全部处理完毕。

executeCommand核心片段
status_t IPCThreadState::executeCommand(int32_t cmd) {
    // ...省略部分
    if (tr.target.ptr) {
        // 普通Binder服务
        if (reinterpret_cast<RefBase::weakref_type*>(tr.target.ptr)->attemptIncStrong(this)) {
            error = reinterpret_cast<BHwBinder*>(tr.cookie)->transact(tr.code, buffer, &reply, tr.flags, reply_callback);
            reinterpret_cast<BHwBinder*>(tr.cookie)->decStrong(this);
        } else {
            error = UNKNOWN_TRANSACTION;
        }
    } else {
        // context manager对象,特指ServiceManager
        error = the_context_object->transact(tr.code, buffer, &reply, tr.flags, reply_callback);
    }
}
  • 说明

    • 普通服务:通过BBinder子类(如BnXXXService)的transact/onTransact处理
    • context对象(ServiceManager):直接走ServiceManager的transact

BBinder转发至onTransact

status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    data.setDataPosition(0);
    status_t err = NO_ERROR;
    switch (code) {
        case PING_TRANSACTION:
            err = pingBinder();
            break;
        case EXTENSION_TRANSACTION:
            err = reply->writeStrongBinder(getExtension());
            break;
        case DEBUG_PID_TRANSACTION:
            err = reply->writeInt32(getDebugPid());
            break;
        default:
            err = onTransact(code, data, reply, flags);
            break;
    }
    if (reply != nullptr) {
        reply->setDataPosition(0);
    }
    return err;
}
  • 说明:BBinder只做分发,所有核心命令最终都落到具体的服务子类(如ServiceManager)的onTransact实现。

三、服务端整体流程总结

源码主链路

驱动 ioctl → looper回调(BinderCallback) → IPCThreadState::self()->handlePolledCommands() → BBinder::transact → BnServiceManager::onTransact → ServiceManager::getService()

服务端流程图


补充说明

  • 服务端处理的主流程其实就是:

    1. Binder驱动通过ioctl事件通知
    2. Looper/BinderCallback监听fd
    3. IPCThreadState循环获取并解析命令
    4. 真正业务转发到ServiceManager对象或其它服务对象的onTransact处理
  • ServiceManager作为全局context对象,具有特殊性:
    它的注册、管理、转发能力保障了整个系统服务发现与通信体系的稳定运转。

学后检测

单选题

1. ServiceManager进程在Android系统中的启动时机是?

A. Zygote启动后
B. SystemServer启动后
C. init.rc解析时,早于Zygote
D. 应用层启动后

答案:C
解析: ServiceManager属于系统原生守护服务,最早在init.rc阶段启动。


2. ServiceManager在注册为Binder的context manager时调用了哪个类的静态方法?

A. BBinder::becomeContextManager
B. ProcessState::becomeContextManager
C. IPCThreadState::setTheContextObject
D. ServiceManager::addService

答案:B
解析: 注册全局上下文管理者是ProcessState::becomeContextManager()。


多选题

3. 关于IPCThreadState,以下说法正确的是?

A. 每个进程只有一个IPCThreadState实例
B. 通过TLS(线程本地存储)实现线程隔离
C. 负责管理当前线程与Binder驱动的交互
D. 在每个线程中都是单例模式

答案:B、C、D
解析: IPCThreadState是线程级别的单例,通过TLS实现,负责当前线程与Binder交互。A错,每线程一个。


4. ServiceManager主循环中pollAll(-1)的作用有哪些?

A. 持续监听Binder fd
B. 监听并响应Binder事件
C. 只监听一次事件,处理完即退出
D. 支持阻塞模式下的事件分发

答案:A、B、D
解析: pollAll(-1)为无限阻塞监听,持续处理事件。


判断题

5. ServiceManager的BBinder对象本身实现了所有onTransact的业务处理。

(对/错)

答案:错
解析: BBinder只做分发,具体业务由ServiceManager或其子类实现onTransact。


6. BinderCallback用于监听Binder文件描述符事件,并转发给IPCThreadState处理。

(对/错)

答案:对
解析: 其本质是fd事件回调分发器。


简答题

7. 简述ServiceManager启动主流程(从main函数到业务分发),并说明其成为Binder全局context对象的原理。

答案:

  1. main函数首先初始化Binder驱动(ProcessState::initWithDriver),实例化ServiceManager并自注册addService("manager",...)。
  2. 调用IPCThreadState::setTheContextObject将自身设置为Binder上下文对象。
  3. ProcessState::becomeContextManager()将ServiceManager注册为驱动层的context manager(handle为0的特殊Binder实体)。
  4. Looper初始化并通过BinderCallback::setupTo注册监听Binder fd事件,回调时调用IPCThreadState::handlePolledCommands(),最终分发到ServiceManager的onTransact实现处理具体业务。

8. 为什么ServiceManager的crash或重启会影响到healthd、zygote等核心系统服务?

答案:
因为所有系统服务的发现、注册、Binder通信都依赖ServiceManager。如果它崩溃,所有通过Binder发现的服务都会失效。init.rc中配置有依赖关系,重启ServiceManager会自动重启相关核心服务以保障系统一致性。


源码填空题

9. 在ServiceManager进程main()函数中,设置Binder全局上下文管理者用到的两步核心调用分别是( 1 )和( 2 )。

答案:

  1. IPCThreadState::self()->setTheContextObject(manager);
  2. ProcessState::becomeContextManager(nullptr, nullptr);

10. 在BinderCallback的handleEvent()方法内部,实际负责解析Binder命令与分发的函数是( )。

答案:IPCThreadState::handlePolledCommands()
解析: 它会循环调用getAndExecuteCommand,最终通过executeCommand分发到BBinder或ServiceManager。