虽可儿的小窝

Thoughts, stories and ideas.

0%

二 注册服务(addService)

1 概述

学习 Binder 机制,我们先从注册服务开始。所谓注册服务,就是指 Server 将自己的 Binder 实体通过一次 IPC 通信,在 ServiceManager 那里完成登记。

以 Media 服务注册进行说明。

1.1 Media 服务注册

Media 的入口函数是 main_mediaserver.cpp 中的 main() 方法。在 Android 早期,路径是:/frameworks/base/media/mediaserver/main_mediaserver.cpp

从 Android 7 开始路径迁移至 /frameworks/av/media/mediaserver/main_mediaserver.cpp

namespace {
    constexpr int kCodecThreadPoolCount = 16;

    // This is the default thread count for binder thread pool
    // if the thread count is not configured.
    constexpr int kDefaultBinderThreadPoolCount = 15;
}; // anonymous

int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);

	// 注册前准备 和 获取 ServiceManager 代理。
	// 打开 /dev/binder 驱动,完成 Binder 通信的初始化
    sp<ProcessState> proc(ProcessState::self());
	// 通过 Binder 驱动获取到 ServiceManager 的代理对象
    sp<IServiceManager> sm(defaultServiceManager());
    ALOGI("ServiceManager: %p", sm.get());

	// 服务注册 的核心调用
    MediaPlayerService::instantiate();
    ResourceManagerService::instantiate();
    registerExtensions();

	// 设置 Binder 线程池
    bool aidl = ::android::IsCodec2AidlHalSelected();
    if (!aidl) {
        ::android::hardware::configureRpcThreadpool(kCodecThreadPoolCount, false);
    } else {
        ABinderProcess_setThreadPoolMaxThreadCount(
                kCodecThreadPoolCount + kDefaultBinderThreadPoolCount);
    }
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

流程说明:

  1. 打开 /dev/binder 驱动,获取 ProcessState 对象
  2. 获取 ServiceManager 的代理对象
  3. 注册服务,(Android 6 的时候,需要注册多种服务,而 Android 16 只需要注册两个即可)
  4. 设置 Binder 线程池

本文的重点是讲解 Native 层服务注册的过程。

1.2 类图

在 Native 层的服务,以 Media 为例,来讲解服务注册过程,下面是 Media 的整个类关系图。

  • 蓝色代表的是注册 MediaPlayerService 服务所涉及的类
  • 绿色代表的是 Binder 架构中与 Binder 驱动通信过程中的最为核心的两个类;
  • 紫色代表的是注册服务和获取服务的公共接口/父类;

理解这个类图:

  1. 首先 RefBase 相关的先忽略,这个是引用计数管理器,BBinder 和各类具体服务都继承自它,Android 的智能指针 sp 和 wp 才能自动管理对象的生命周期。但是对分析流程无用,只要知道这个是干啥的即可。
  2. 然后从 Interface 来看,这个是接口层,下面的 IMediaPlayerService 就是具体的 Media 的服务接口。后续分成了两个接口,一个是客户端接口(客户端代理),一个是服务端接口(服务端骨架)。
  3. BpInterface 客户端模板类,负责实现代理功能,下面的 BpMediaPlayerService 就是具体的客户端代理实现。里面是持有 BpBinder 的。
  4. BnInterface 服务端模板类,负责实现骨架功能,类似的,BnMediaPlayerService 就是具体的服务端骨架实现。里面是继承 BBinder 的。
  5. 接下来看右边部分,IBinder 是 Android Binder IPC 机制的核心接口。
  6. 下面分为两个部分,服务端与客户端,都继承了 IBinder,分别是 BBinder 和 BpBinder。BBinder 是真正的 Binder 实体,为本地对象。BpBinder 是 Binder 的代理,为远程句柄。
  7. ProcessState 进程级单例,管理与驱动的连接,每个进程一个,负责“连上 Binder 驱动”。IPCThreadState 线程级单例,管理 IPC 收发与线程池,每个线程一个,负责“真正收发 Binder 数据”。几乎所有 Binder 调用最终都会经过它们。

在新架构中,其实增加了 CppBackendShim 兼容层,这个层的引入并没有废除这套基础设计,而是叠加在它之上,暂时不做分析。

1.3 时序图

接下来看看时序图吧,来说明一下 Media 服务启动过程是如何向 ServiceManager 注册服务的。

2 ProcessState

从 1.1 可以看出,是先获取的 ProcessState 对象,所以我们从这里先看起。

涉及到的文件是 ProcessState.cpp,路径在 frameworks/native/libs/binder

2.1 ProcessState::self

sp<ProcessState> ProcessState::self()
{
    return init(kDefaultDriver, false /*requireDefault*/);
}

首先,使用的是 self 方法,self 又调用了私有的 init 方法,并传递了参数 kDefaultDriver,通常是 /dev/binder)和 false 作为 requireDefault 参数。

sp<ProcessState> ProcessState::init(const char* driver, bool requireDefault) {
    ALOGI("ProcessState::init called with driver=%s, requireDefault=%d",
          driver ? driver : "nullptr", requireDefault);

    // 分支1:传入 driver 为 nullptr,直接返回已有的单例(如果有)
    if (driver == nullptr) {
        ALOGI("ProcessState::init: driver is null, attempting to return existing instance");
        std::lock_guard<std::mutex> l(gProcessMutex);
        if (gProcess) {
            ALOGI("ProcessState::init: existing gProcess found (%p), verifying fork status", gProcess.get());
            verifyNotForked(gProcess->mForked);
        } else {
            ALOGI("ProcessState::init: no existing gProcess, returning nullptr");
        }
        return gProcess;
    }

    // 分支2:首次初始化,使用 std::call_once 确保只执行一次
    [[clang::no_destroy]] static std::once_flag gProcessOnce;
    std::call_once(gProcessOnce, [&](){
        ALOGI("ProcessState::init: first time initialization for driver=%s", driver);

        // 2.1 检查驱动文件是否可访问
        if (access(driver, R_OK) == -1) {
            ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.", driver);
            driver = "/dev/binder";
        } else {
            ALOGI("ProcessState::init: driver %s is accessible", driver);
        }

        // 2.2 检查 vndbinder 相关的服务是否启用
        if (0 == strcmp(driver, "/dev/vndbinder") && !isVndservicemanagerEnabled()) {
            ALOGE("vndservicemanager is not started on this device, you can save resources/threads "
                  "by not initializing ProcessState with /dev/vndbinder.");
        }

        // 2.3 注册 fork 处理函数
        int ret = pthread_atfork(ProcessState::onFork, ProcessState::parentPostFork,
                                 ProcessState::childPostFork);
        if (ret != 0) {
            ALOGE("pthread_atfork error %s", strerror(ret));
            LOG_ALWAYS_FATAL_IF(ret != 0, "pthread_atfork error %s", strerror(ret));
        } else {
            ALOGI("ProcessState::init: pthread_atfork handlers installed successfully");
        }

        // 2.4 加锁创建 gProcess 实例
        {
            std::lock_guard<std::mutex> l(gProcessMutex);
            gProcess = sp<ProcessState>::make(driver);
            ALOGI("ProcessState::init: gProcess created (%p) with driver=%s",
                  gProcess.get(), driver);
        }
    });

    // 分支3:requireDefault 检查
    if (requireDefault) {
        ALOGI("ProcessState::init: requireDefault is true, checking driver consistency");
        if (gProcess->getDriverName() != driver) {
            ALOGE("ProcessState was already initialized with %s, can't initialize with %s.",
                  gProcess->getDriverName().c_str(), driver);
            LOG_ALWAYS_FATAL_IF(gProcess->getDriverName() != driver,
                                "ProcessState was already initialized with %s,"
                                " can't initialize with %s.",
                                gProcess->getDriverName().c_str(), driver);
        }
    }

    // 最终检查 fork 状态
    verifyNotForked(gProcess->mForked);
    ALOGI("ProcessState::init: returning gProcess (%p) with driver=%s",
          gProcess.get(), gProcess->getDriverName().c_str());
    return gProcess;
}

init 方法中涉及到的东西就很多了,Android 6 逻辑会简单很多,Android 16 在安全、容错和灵活性上做了大量增强。核心目标是一致的:确保每个进程只创建一个 ProcessState单例

2.2 ProcessState 初始化

我们来看下是怎么进行初始化的,也就是 gProcess = sp::make(driver) 这个方法。这里的 make 并不是 ProcessState 的方法,而是 C++ 智能指针 sp 提供的一个静态工厂方法。这个方法的最终动作就是调用 ProcessState 的构造方法,我们暂时不关心是怎么实现的。

来看 ProcessState 的构造方法:

ProcessState::ProcessState(const char* driver)
    // ---- 初始化列表:为所有成员变量赋予安全的初始值 ----
    : mDriverName(String8(driver)),        // 保存驱动名称(如 "/dev/binder")
      mDriverFD(-1),                       // 驱动文件描述符先设为 -1(无效值)
      mVMStart(MAP_FAILED),                // 共享内存映射起始地址先设为 MAP_FAILED(无效)
      mExecutingThreadsCount(0),           // 当前正在执行 binder 事务的线程数,初始为 0
      mMaxThreads(DEFAULT_MAX_BINDER_THREADS), // 向驱动申请的最大 binder 线程数(默认 15)
      mCurrentThreads(0),                  // 当前进程中的 binder 线程总数,初始 0
      mKernelStartedThreads(0),            // 由内核启动的 binder 线程计数,初始 0
      mStarvationStartTime(never()),       // 线程饥饿计时起点,初始为“永不”表示未饥饿
      mForked(false),                      // 标记进程是否经历过 fork,初始为 false
      mThreadPoolStarted(false),           // 标记线程池是否已启动,初始为 false
      mThreadPoolSeq(1),                   // 线程池编号,用于生成线程名
      mCallRestriction(CallRestriction::NONE) // 调用限制策略,初始为“无限制”
{
    String8 error;  // 用于保存 open_driver 失败时的错误信息

    // 1. 尝试打开 Binder 驱动,并进行协议协商与配置
    unique_fd opened = open_driver(driver, &error);

    // 2. 如果驱动打开成功,立即建立内存映射(mmap)
    if (opened.ok()) {
        // mmap 用于在进程的虚拟地址空间中预留一块区域,
        // 让 Binder 驱动可以直接将其他进程发来的数据写入此处,减少拷贝。
        mVMStart = mmap(nullptr,
                        BINDER_VM_SIZE,                // 映射大小(约 1MB - 2页)
                        PROT_READ,                     // 只允许进程读取(驱动拥有写入权限)
                        MAP_PRIVATE | MAP_NORESERVE,   // 私有映射,不保留 swap 空间
                        opened.get(),                  // 驱动文件描述符
                        0);
        if (mVMStart == MAP_FAILED) {
            // 如果映射失败,记录错误日志,并且关闭已打开的驱动文件描述符
            ALOGE("Using %s failed: unable to mmap transaction memory.", driver);
            opened.reset();          // 关闭 fd 并置为无效
            mDriverName.clear();     // 清除驱动名称,表示初始化失败
        }
    }

    // 3. 根据平台宏,决定驱动打开失败时的处理策略
#if defined(EXPECT_BINDER_OPEN_SUCCESS)
    // Android / Fuchsia 等平台:驱动必须打开成功,否则视为致命错误,直接终止进程。
    LOG_ALWAYS_FATAL_IF(!opened.ok(),
                        "Binder driver '%s' could not be opened. Error: %s. Terminating.",
                        driver, error.c_str());
#else
    // 其他平台:驱动打开失败仅记录错误,进程可能降级运行(后续功能可能异常)。
    if (!opened.ok()) {
        ALOGE("Binder driver '%s' could not be opened. Error: %s. There may be future issues.",
              driver, error.c_str());
    }
#endif

    // 4. 保存可用的驱动文件描述符,供后续所有 Binder 通信使用
    if (opened.ok()) {
        // 从 unique_fd 中释放所有权,将原始的 fd 值赋给 mDriverFD
        mDriverFD = opened.release();
    }

    // 5. 如果需要 Binder 事件观察者(调试用),则创建它
#ifdef BINDER_WITH_OBSERVERS
    mBinderObserver = std::make_unique<BinderObserver>();
#endif
}

2.3 open_driver

open_driver 负责打开 Binder 驱动并完成所有必要的初始化协商。

static unique_fd open_driver(const char* driver, String8* error) {
    // 1. 打开 Binder 驱动设备文件
    // O_RDWR   : 可读可写,用于收发 Binder 事务
    // O_CLOEXEC: 进程执行新程序时自动关闭该 fd,防止泄露
    auto fd = unique_fd(open(driver, O_RDWR | O_CLOEXEC));
    if (!fd.ok()) {
        // 打开失败,记录详细错误信息到 error 中,并返回空 unique_fd
        error->appendFormat("%d (%s) Opening '%s' failed", errno, strerror(errno), driver);
        return {};
    }

    // 2. 协商 Binder 协议版本
    int vers = 0;
    int result = ioctl(fd.get(), BINDER_VERSION, &vers);
    if (result == -1) {
        // ioctl 调用本身失败(比如驱动不支持此命令)
        error->appendFormat("%d (%s) Binder ioctl to obtain version failed", errno,
                            strerror(errno));
        return {};
    }
    if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
        // 用户空间库与内核驱动的协议版本不匹配,无法协同工作
        error->appendFormat("Binder driver protocol(%d) does not match user space protocol(%d)! "
                            "ioctl() return value: %d",
                            vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
        return {};
    }

    // 3. 设置进程允许的最大 Binder 线程数
    // 告诉驱动本进程最多能有多少个线程同时处理 Binder 事务
    size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
    result = ioctl(fd.get(), BINDER_SET_MAX_THREADS, &maxThreads);
    if (result == -1) {
        ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
    }

    // 4. 开启单向(oneway)调用垃圾检测
    // 该功能用于检测是否有进程滥用 oneway 调用导致事务堆积
    uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
    result = ioctl(fd.get(), BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
    if (result == -1) {
        ALOGE_IF(ProcessState::isDriverFeatureEnabled(
                     ProcessState::DriverFeature::ONEWAY_SPAM_DETECTION),
                 "Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
    }

    // 返回已配置好的文件描述符
    return fd;
}

open_driver 作用是打开 /dev/binder 设备,设定 binder 支持的最大线程数。关于 binder 驱动的相应方法之后会再看。

ProcessState 采用单例模式,保证每一个进程都只打开一次 Binder Driver。

2.4 小结

通过上面的分析,ProcessState 的初始化过程调用链就可以梳理出来了。

main()
  → ProcessState::self()
      → ProcessState::init(kDefaultDriver, false)
          → sp<ProcessState>::make(driver)
              → ProcessState::ProcessState(driver)
                  → open_driver(driver, &error)
                  → mmap(nullptr, BINDER_VM_SIZE, ...)
                  → mDriverFD = opened.release()

main() 作为进程入口,首先调用 ProcessState::self() 来初始化 Binder 通信基础设施。

self() 是获取进程单例的标准入口,它不做实际工作,直接把请求委托给 ProcessState::init(kDefaultDriver, false),其中 kDefaultDriver 通常是 /dev/binder。

init 是初始化的逻辑核心,它使用 std::call_once 机制确保无论多少线程同时调用,真正的构造逻辑只执行一次,同时它还负责检查进程是否经历过 fork 以确保安全。在确认可以创建实例后,init 调用 sp::make(driver),这是智能指针 sp 提供的工厂方法,相当于在堆上执行 new ProcessState(driver) 并立即用 sp 接管其生命周期。

接下来进入 ProcessState 的构造函数 ProcessState::ProcessState(driver),它先将所有成员变量初始化为安全的默认值,然后调用 open_driver(driver, &error) 打开 Binder 驱动设备文件,依次完成文件打开、协议版本协商、最大线程数设置以及 oneway 调用检测开启这四个关键步骤。

驱动打开成功后,构造函数接着调用 mmap(nullptr, BINDER_VM_SIZE, ...) 在进程的虚拟地址空间中预留一块共享内存区域,让 Binder 驱动能够直接将跨进程事务数据写入此处,从而避免数据拷贝、提升通信效率。

最后,构造函数执行 mDriverFD = opened.release(),将临时对象中已打开的驱动文件描述符转移到成员变量 mDriverFD 中永久保存,供后续所有 Binder 操作使用。

至此,ProcessState 初始化完成,返回一个指向进程唯一实例的智能指针,进程已经具备完整的 Binder 通信能力,可以开始向 ServiceManager 注册服务或与其他进程进行 IPC 通信了。

3 服务注册

如何获取 ServiceManager 的之后再讲解。

  • [X] 获取 ServiceManager

四 获取 ServiceManager

接下来进入到服务注册的流程,也就是下面这些

MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();

3.1 instantiate

这个就是一个静态方法嘛,例如 MediaPlayerService 的,路径在 frameworks/av/media/libmediaplayerservice 下。

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

它首先通过 defaultServiceManager() 返回 ServiceManager 的代理对象,这个代理对象实现了 IServiceManager 接口,内部使用 CppBackendShim 作为兼容层。

在这个方法的执行过程中,会触发创建 ProcessState 对象和 BpBinder 对象(如果已经存在,则不创建,直接复用)。代理对象继承自 BpInterface,而 BpInterface 又继承自 BpRefBase。BpRefBase 在构造时需要持有一个 BpBinder 对象,要拿到这个 BpBinder,最终会调用到 ProcessState::self()。

然后代理对象调用 addService 方法,把服务名和服务对象传进去。在内部,这个调用被 CppBackendShim 拦截并转发给新的统一服务管理器完成注册。

3.2 addService

继续往下看,addService 是怎么实现的。路径在 frameworks/native/libs/binder/IServiceManager.cpp

为啥知道是这里?和 defaultServiceManager() 的实现有关,返回的就是 IServiceManager 对象,具体类型就是 CppBackendShim。

status_t CppBackendShim::addService(const String16& name, const sp<IBinder>& service,
                                    bool allowIsolated, int dumpsysPriority) {
    Status status = mUnifiedServiceManager->addService(String8(name).c_str(), service,
                                                       allowIsolated, dumpsysPriority);
    return status.exceptionCode();
}

这里就是通过 CppBackendShim 将老接口的调用,原封不动地转发给新架构的“统一服务管理器”。

在 Android 11 之前,是通过 BpServiceManager 直接进行 IPC 的。

现在的逻辑和 3.1 类似,调用的是 BackendUnifiedServiceManager 的方法。

接下来这个 addService 是在,frameworks/native/libs/binder/BackendUnifiedServiceManager.cpp

Status BackendUnifiedServiceManager::addService(const ::std::string& name,
                                                const sp<IBinder>& service,
                                                bool allowIsolated,
                                                int32_t dumpPriority) {
    // 检查真正的 ServiceManager 代理是否存在
    // 如果系统正常启动,servicemanager 进程会初始化这个指针
    if (mTheRealServiceManager) {
        // 将注册请求转发给真正的 ServiceManager 进程
        // 这一调用会通过 Binder 跨进程到达 ServiceManager.cpp 中的 addService 方法
        Status status =
                mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);

        // 检查是否满足缓存条件:
        // 1. 全局缓存开关 kUseCacheInAddService 为 true(默认开启)
        // 2. 实例级缓存开关 mEnableAddServiceCache 为 true(默认 true)
        // 3. 注册操作成功(status.isOk())
        if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) {
            // 将新注册的服务信息写入本地缓存,方便后续 getService 查询时直接返回,
            // 避免再次跨进程调用,提升性能
            return updateCache(name, service,
                               dumpPriority & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE);
        }
        // 不满足缓存条件时,直接返回来自 servicemanager 的注册结果
        return status;
    }

    // 如果 mTheRealServiceManager 为空(servicemanager 未就绪),
    // 则返回“不支持的操作”错误,并附带错误信息
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}

这里有调用了 mTheRealServiceManager->addService 了,又一个 addService,这里使用的是 AIDL,会调用代理方法,被转发给自动生成的 BpServiceManager 代理类。最终就是调用到 ServiceManager.cpp 里的 addService 方法。

  • [ ] AIDL 讲解

路径在:frameworks/native/cmds/servicemanager/ServiceManager.cpp

Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder,
                                  bool allowIsolated, int32_t dumpPriority) {
    // 性能追踪宏,用于 systrace/perfetto 抓取
    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
            PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));

    // 获取调用者的身份上下文(UID、PID、SID 等)
    auto ctx = mAccess->getCallingContext();

    // --- 安全检查 1:应用 UID 不允许注册系统服务 ---
    if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
        return Status::fromExceptionCode(Status::EX_SECURITY, "App UIDs cannot add services.");
    }

    // --- 安全检查 2:检查调用者是否有权限添加此服务 ---
    // 会校验 SELinux 权限以及 allowed 列表等
    std::optional<std::string> accessorName;
    if (auto status = canAddService(ctx, name, &accessorName); !status.isOk()) {
        return status;
    }

    // --- 参数校验:binder 对象不能为空 ---
    if (binder == nullptr) {
        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Null binder.");
    }

    // --- 参数校验:服务名必须是合法格式 ---
    if (!isValidServiceName(name)) {
        ALOGE("%s Invalid service name: %s", ctx.toDebugString().c_str(), name.c_str());
        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid service name.");
    }

#ifndef VENDORSERVICEMANAGER
    // --- VINTF 兼容性检查(仅系统 servicemanager)---
    // 确保服务在 VINTF manifest 中正确声明
    if (!meetsDeclarationRequirements(ctx, binder, name)) {
        return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "VINTF declaration error.");
    }
#endif  // !VENDORSERVICEMANAGER

    // 如果 dump 优先级没有设置任何有效位,打一个警告
    if ((dumpPriority & DUMP_FLAG_PRIORITY_ALL) == 0) {
        ALOGW("%s Dump flag priority is not set when adding %s", ctx.toDebugString().c_str(),
              name.c_str());
    }

    // --- 注册死亡通知 ---
    // 当服务端 binder 死亡时,servicemanager 会收到回调以便自动清理
    if (binder->remoteBinder() != nullptr &&
        binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
        ALOGE("%s Could not linkToDeath when adding %s", ctx.toDebugString().c_str(), name.c_str());
        return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "Couldn't linkToDeath.");
    }

    // --- 处理重复注册 ---
    auto it = mNameToService.find(name);
    bool prevClients = false;
    if (it != mNameToService.end()) {
        const Service& existing = it->second;
        prevClients = existing.hasClients;

        // 如果前后两次注册的 UID 不同,可能是多个服务实例冲突
        if (existing.ctx.uid != ctx.uid) {
            ALOGW("Service '%s' originally registered from UID %u but it is now being registered "
                  "from UID %u. Multiple instances installed?",
                  name.c_str(), existing.ctx.uid, ctx.uid);
        }

        // 如果前后两次注册的 SELinux SID 不同,同样警告
        if (existing.ctx.sid != ctx.sid) {
            ALOGW("Service '%s' originally registered from SID %s but it is now being registered "
                  "from SID %s. Multiple instances installed?",
                  name.c_str(), existing.ctx.sid.c_str(), ctx.sid.c_str());
        }

        ALOGI("Service '%s' originally registered from PID %d but it is being registered again "
              "from PID %d. Bad state? Late death notification? Multiple instances installed?",
              name.c_str(), existing.ctx.debugPid, ctx.debugPid);
    }

    // --- 核心操作:将服务信息写入全局列表 ---
    // 同名服务会被直接覆盖,新服务替换旧服务
    mNameToService[name] = Service{
            .binder = binder,              // 服务的 Binder 实体对象
            .allowIsolated = allowIsolated, // 是否允许沙箱应用访问
            .dumpPriority = dumpPriority,  // dumpsys 优先级
            .hasClients = prevClients,     // 保留旧的客户端状态
            .guaranteeClient = false,      // 是否需要通知等待中的客户端
            .ctx = ctx,                    // 注册者的身份上下文
    };

    // --- 通知正在等待此服务的客户端 ---
    // 如果有客户端先调用了 getService 但服务尚未注册,它们会注册回调在此等待
    if (auto it = mNameToRegistrationCallback.find(name);
        it != mNameToRegistrationCallback.end()) {
        // 标记该服务有客户端正在等待
        mNameToService[name].guaranteeClient = true;
        // 处理服务客户端回调,通知等待者
        CHECK(handleServiceClientCallback(2 /* sm + transaction */, name, false));
        mNameToService[name].guaranteeClient = true;

        // 逐个通知所有注册了回调的客户端
        for (const sp<IServiceCallback>& cb : it->second) {
            cb->onRegistration(name, binder);
        }
    }

    // 返回成功
    return Status::ok();
}

主要看核心的注册操作

mNameToService[name] = Service{
        .binder = binder,
        .allowIsolated = allowIsolated,
        .dumpPriority = dumpPriority,
        .hasClients = prevClients,
        .guaranteeClient = false,
        .ctx = ctx,
};

它把服务名 name(如 "media.player")作为键,将包含服务 Binder 实体、访问权限、优先级等信息的 Service 结构体作为值,存入 servicemanager 进程的全局 map mNameToService 中。

这样就算是登记了,其他进程就可以通过服务名查询到这个 Binder 引用,从而发起远程调用。

3.3 小结

新架构的的路径经过了多层的包装

BpServiceManager::addService()
  → CppBackendShim::addService()
    → BackendUnifiedServiceManager::addService()
      → mTheRealServiceManager->addService()  // AIDL 代理
        → Binder 驱动
        → ServiceManager::addService()  // 真正的注册

旧架构就直接很多

BpServiceManager::addService()
  → 手动打包 Parcel
  → BpBinder(0)->transact(ADD_SERVICE_TRANSACTION)
  → Binder 驱动
  → servicemanager 进程

可以这么记忆,

  • Android 6:服务注册 → 插入全局链表 svclist
  • Android 16:服务注册 → 写入全局 map mNameToService
Suikeer

关于作者